2016-12-15 14 views
0

2015年と2016年の各月の行を返すSQLクエリが必要です。結果として得られたデータセットには、企業がどの暦月にもヌル値で料金を支払っていない月が表示されます。問題は、彼らが会費を払わなかった場合、彼らはデータベースにエントリーを持たないので、月よりも行が出現しないということです。ここでは、クエリです:データがテーブルにない場合でも列を表示する

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社は、6月を除いて2015年に毎月支払われたと支払っていない企業を見つけることですNULL値を持つ会社XYZ、または支払を見落としたゼロまたはその他のインジケータの6月の行。今のように、行は単純に省略されます。これは、データが存在しないためで、数千または行のうち欠けている行を見つけることが難しいためです。

私はそれがおそらく異なる種類の結合または何かであることを認識していますが、私はうまく動作しません。あなたは数ヶ月のためにダミーのテーブルを作成することができます

+0

どのバージョンのSQL Serverですか? –

+0

申し訳ありません。 SQL 2012.特に12.0.2000.8 – ekim110575

答えて

0

1にそれを参加しますそのように左)1からのすべての月の生成再帰的な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

ありがとう、あなたのソリューションはうまくいきました。私は過去に数回十字結合を使用していて、あまりにも快適ではありませんでした。私はあなたの質問に少し微調整を加えましたが、あなたがそれを書いたときにすべての細部を持っていなかったからです。しかし、それに1行のコードを追加するだけで、魅力的に働き、巧みに私の問題を解決しました。 – ekim110575

1

、それにdbo.Activityに参加するあなたはすべての月を取得し、その後dbo.Name

+0

ありがとうございます。このソリューションはvkpのソリューションと同様に機能しました。全体的にコードが少なく、少し速く実行されたので、彼と一緒に行きましたが、あなたのソリューションは効果的でした。助けてくれてありがとう。 – ekim110575

関連する問題