2016-12-15 61 views
0

我需要一個SQL查詢來爲每個支付會費的公司在2015年和2016年的每個月返回一行。由此產生的數據集將顯示公司未支付空值的月份。問題是,如果他們沒有支付會費,他們將不會在數據庫中輸入數據,因此不會出現超過一個月的行。下面是該查詢:即使數據從表中缺失,也顯示一行

SELECT 
case when n.co_id <>'' then n.co_id else n.ID end ID 
,su.CONTINUOUS_SINCE 
,n.COMPANY 
,a.EFFECTIVE_DATE 
, a.AMOUNT 


FROM dbo.Name n 
LEFT OUTER JOIN dbo.Activity a ON n.ID = a.ID 
inner JOIN dbo.Loc_Info l ON n.ID = l.ID 
inner JOIN dbo.Segment_Categories s ON l.CURRENT_SEGMENT = s.CODE 
inner JOIN dbo.Subscriptions su on su.id=n.id 

WHERE   a.PRODUCT_CODE='rental' and n.MEMBER_TYPE in ('rb','rl') and a.EFFECTIVE_DATE Between '2015-07-01' And GetDate() AND a.ACTIVITY_TYPE='dues' 
order by case when n.co_id <>'' then n.co_id else n.ID end, EFFECTIVE_DATE asc 

如果公司已經支付它工作了罰款每月但關鍵是要找到那些沒有支付那麼假設XYZ公司每個月都在2015年支付,除了六月份我就需要一個公司對於公司XYZ的六月份行具有空值或零或其他指標,因此他們錯過了付款。就目前而言,行被簡單地省略,因爲數據不存在,並且很難從數千或行中找到缺失的行。

我意識到它可能是一種不同類型的連接或某些東西,但我只是沒有得到它的工作。

+0

什麼版本的SQL Server? –

+0

對不起。 SQL 2012.特別是12.0.2000.8 – ekim110575

回答

0

1)生成所有從1至數月12遞歸cte。

2)獲取所有的月份和公司的組合與cross join

3)left join對此結果集顯示丟失的月份。

with months as (select 1 mth 
       union all 
       select mth+1 from months where mth<12) 
,yearmonthscompanies as (select * 
         from months m 
         cross join (select 2015 yr union all select 2016 yr) y 
         cross join (select distinct id,co_id,company from name) c 
         ) 
SELECT 
case when ymc.co_id <>'' then ymc.co_id else ymc.ID end ID 
,su.CONTINUOUS_SINCE 
,ymc.COMPANY 
,coalesce(a.effective_date,datefromparts(ymc.yr,ymc.mth,1)) as effective_date 
,coalesce(a.AMOUNT,0) amount 
FROM yearmonthscompanies ymc 
LEFT JOIN dbo.Name n ON n.co_id=ymc.co_id and n.id=ymc.id and n.company=ymc.company 
LEFT JOIN dbo.Activity a ON n.ID = a.ID and a.PRODUCT_CODE='rental' 
and n.MEMBER_TYPE in ('rb','rl') and a.EFFECTIVE_DATE Between '2015-07-01' and GetDate() 
and a.ACTIVITY_TYPE='dues' 
and year(a.effective_date) = ymc.yr and month(a.effective_date) = ymc.mth 
inner JOIN dbo.Loc_Info l ON n.ID = l.ID 
inner JOIN dbo.Segment_Categories s ON l.CURRENT_SEGMENT = s.CODE 
inner JOIN dbo.Subscriptions su on su.id=n.id 
order by case when ymc.co_id <>'' then ymc.co_id else ymc.ID end 
,effective_date 
+0

謝謝,您的解決方案運行良好。我過去只使用了幾次交叉連接,並且對它們不太舒服。我對你的查詢做了一些調整,但僅僅是因爲你在寫代碼的時候並沒有所有的細節,但我只需要添加一行代碼,它就像一個魅力,熟練地解決了我的問題。 – ekim110575

1

您可以創建換了個一個虛表,左側加入dbo.Activity吧,這樣你會得到所有的幾個月裏,然後加入,爲dbo.Name

+0

謝謝,這個解決方案和vkp的解決方案一樣工作。我和他一起去了,因爲它整體代碼更少,執行速度更快,但是您的解決方案也很有效。謝謝您的幫助。 – ekim110575

相關問題