2016-12-27 17 views
0

私はSQL Serverを初めて使用しており、条件付きステートメントを使用して計算された行の合計に関する質問があります。SQL Server:Nヶ月以内の計算された行の合計

次のように私のデータが編成されています。

ID S_DATE  END_DATE MNum CHG DateCHG 
--------------------------------------------- 
1 1/26/2001 2/26/2001 7 NULL 1 
1 2/27/2001 3/27/2001 8 1  1 
1 3/28/2001 1/9/2003 9 1  21 
1 1/10/2003 3/2/2004 11 2  14 
1 3/3/2004 10/14/2004 10 -1  7 
1 10/15/2004 6/22/2005 9 -1  8 
1 6/23/2005 3/9/2008 8 -1 33 
1 3/10/2008 1899-12-30 0 NULL -1299 
2 9/23/1993 9/11/2000 3 NULL 84 
2 1/1/1999 12/31/1998 3 0 -1 
2 9/12/2000 11/13/2001 2 -1 14 
2 11/14/2001 1899-12-30 0 NULL -1223 

DateCHGはS_DATE & END_DATEの間の月数に等しいです。前回の3ヶ月以内にCHGが発生したIDごとにCHGのSUMを検索したいと思います。ここで

は私の現在のコードである(注:列ヘッダーが目的をフォーマットするための上記のデータとは異なります。また、私は唯一のクエリ形式でので、このデータベースに書き込むことはできません)

SELECT 
    *, 
    CASE 
     WHEN MratingNum = 0 OR 
      LAG(MratingNum) OVER (OVER BY MAST_ISSU_NUM, RATG_DATETIME) = 0 OR 
      MAST_ISSU_NUM <> LAG(MAST_ISSU_NUM) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) --OR 
      --LAG(MratingNum) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) < 12 OR --By Credit Rating 
      --LAG(MratingNum) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) < 18 
      THEN NULL 
      ELSE CAST(MratingNum AS INT) - LAG(MratingNum) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) 
    END AS CHG, 
    DATEDIFF(month, RATG_DATETIME, RATG_END_DATETIME) AS DateCHG 
FROM 
    MOODYS_DRD.dbo.DEBT_RATG AS t1 
LEFT JOIN 
    sandbox.dbo.RatingMap AS t2 ON t1.RATG_TXT = t2.MratingValue 
WHERE 
    RATG_TYP_CD = 'LT' 
ORDER BY 
    MAST_ISSU_NUM, RATG_DATETIME 

だから、例えば出力が見えますこのような何か:

ID S_DATE .... SumCHG 
1 1/26/2001.... NULL 
1 2/27/2001.... NULL 
1 3/28/2001.... 2 
1 1/10/2003.... NULL 
1 3/3/2004 .... NULL 

私は最善のアプローチは、それが3未満であるDateCHGのローリング合計を計算して、CHG列を合計することであると仮定していますか?皆さんありがとう!

編集:これはかなり複雑なので、別の方法で質問してみましょう。各レコードについて、私はS_DATEから3ヶ月以内にCHGのSUMを検索して見つけたいと思っています。 2001年3月28日には、2/01と1/01が含まれます。 MNumは7から9に変わったので、CHGのSUMは2になります。しかし、3/4以降は過去3か月間に変更がなく、NULLを返します。私はIDごとにこれをやりたがっているので、ID 2から3ヶ月間は重複したくないと思っています。

+0

どのようにあなたの出力例では、それはあなたが求めている何ですか? IDごとに合計SumChgを求めたので、ID = 1が1回だけ返されます。 – Edward

+0

@EdwardはIDごとに重複したくないという意味です。私はすべての行を見て、過去3ヶ月以内にすべての行の合計を見つけたい。 IDごとに2行しかなく、6か月間離れている場合は、NULLを返すことにします。 IDの行が20行あり、3か月以内に2つのデータの「塊」がある場合、それらの塊の合計を探したいと思います。希望は意味をなさないでしょうか? – user5854307

+0

本当にありません。あなたはどういう意味ですか?重複すると、ID = 1とID = 2を混在させたくないと思うでしょう。私の答えをチェックし、そこからあなたが達成しようとしていないことを教えてください.. – Edward

答えて

0

t0およびtは、データのセットアップに使用されます。あなたのテーブルの

with t0 
      as (select * 
       from  (values (1, '1/26/2001', '2/26/2001', 7, null, 1), 
         (1, '2/27/2001', '3/27/2001', 8, 1, 1), 
         (1, '3/28/2001', '1/9/2003', 9, 1, 21), 
         (1, '1/10/2003', '3/2/2004', 11, 2, 14), 
         (1, '3/3/2004', '10/14/2004', 10, -1, 7), 
         (1, '10/15/2004', '6/22/2005', 9, -1, 8), 
         (1, '6/23/2005', '3/9/2008', 8, -1, 33), 
         (1, '3/10/2008', '1899-12-30', 0, null, -1299), 
         (2, '9/23/1993', '9/11/2000', 3, null, 84), 
         (2, '1/1/1999', '12/31/1998', 3, 0, -1), 
         (2, '9/12/2000', '11/13/2001', 2, -1, 14), 
         (2, '11/14/2001', '1899-12-30', 0, null, -1223)) t (ID, S_DATE, END_DATE, MNum, CHG, DateCHG) 
      ), 
     t as (select t0.ID , 
         cast(t0.S_DATE as date) S_DATE , 
         cast(t0.END_DATE as date) END_DATE , 
         t0.MNum , 
         t0.CHG , 
         t0.DateCHG 
       from  t0 
      ) 
    select case when Cnt >= 3 then p.CHG 
      end SumCHG, 
      * 
    from t 
      outer apply (select sum(u.CHG) CHG , 
            count(*) Cnt 
          from  t u 
          where  u.ID = t.ID 
            and u.S_DATE between dateadd(month, -3, 
                   t.S_DATE) 
               and  t.S_DATE 
         ) p 
    order by t.ID , 
     t.S_DATE; 

利用CTE、

;with t as (
SELECT 
    *, 
    CASE 
     WHEN MratingNum = 0 OR 
      LAG(MratingNum) OVER (OVER BY MAST_ISSU_NUM, RATG_DATETIME) = 0 OR 
      MAST_ISSU_NUM <> LAG(MAST_ISSU_NUM) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) --OR 
      --LAG(MratingNum) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) < 12 OR --By Credit Rating 
      --LAG(MratingNum) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) < 18 
      THEN NULL 
      ELSE CAST(MratingNum AS INT) - LAG(MratingNum) OVER (ORDER BY MAST_ISSU_NUM, RATG_DATETIME) 
    END AS CHG, 
    DATEDIFF(month, RATG_DATETIME, RATG_END_DATETIME) AS DateCHG 
FROM 
    MOODYS_DRD.dbo.DEBT_RATG AS t1 
LEFT JOIN 
    sandbox.dbo.RatingMap AS t2 ON t1.RATG_TXT = t2.MratingValue 
WHERE 
    RATG_TYP_CD = 'LT' 
) 
    select case when Cnt >= 3 then p.CHG 
      end SumCHG, 
      * 
    from t 
      outer apply (select sum(u.CHG) CHG , 
            count(*) Cnt 
          from  t u 
          where  u.ID = t.ID 
            and u.S_DATE between dateadd(month, -3, 
                   t.S_DATE) 
               and  t.S_DATE 
         ) p 
    order by t.ID , 
     t.S_DATE; 
+0

これは正しい道のりですが、私の既存のコードにどのように組み込むのか分かりません。私はまだSQLに対して非常に新しく、構文がどこに属しているのかわからない。 – user5854307

+0

'select'部分からちょうど始まる。 't'を' yourDataSource t'に変更してください。 – ca9163d9

+0

あなたの名前は何ですか? – ca9163d9

関連する問題