2017-04-11 17 views
0

私はパーティションの行数を数えたいと思う0-3ヶ月。月は、1月2016日に201601のような形式でMYMONTHによって指定されます。私はSQL Server 2014を使用しています。どのように3か月間にパーティションを実行できますか?SQL Server:3か​​月分のパーティションを作成する方法?

SELECT COUNT(*), 
     COUNT(*) 
     / 
     (COUNT(*) OVER (PARTITION 
      BY MYMONTH RANGE BETWEEN 3 MONTH PRECEDING AND CURRENT MONTH)) 
FROM myData 

サンプル

| Month | Value | ID | 
-------------------------| 
| 201601 | 1 | X | 
| 201601 | 1 | Y | 
| 201601 | 1 | Y | 
| 201602 | 1 | Z | 
| 201603 | 1 | A | 
| 201604 | 1 | B | 
| 201605 | 1 | C | 
| 201607 | 1 | E | 
| 201607 | 10 | EE | 
| 201607 | 100 | EEE| 

カウント

| Month | Count | Count3M | Count/Count3M | 
------------------------------------------- 
| 201601| 3 | 3 |  3/3  | 
| 201602| 1 | 4 |  1/4  | 
| 201603| 1 | 5 |  1/5  | 
| 201604| 1 | 6 |  1/6  | 
| 201605| 1 | 4 |  1/4  | 
| 201607| 3 | 5 |  3/5  | 
+0

編集ご質問や、サンプルデータと望ましい結果を提供します。 –

+0

@GordonLinoffがサンプルを追加しました。 – hhh

+0

@hhh OK分かった – etsa

答えて

1

あなたはこの(MSSQL 2012)試すことができます。

サンプル・データ

CREATE TABLE mytable(
    MONT INTEGER NOT NULL 
    ,Value INTEGER NOT NULL 
    ,ID VARCHAR(5) NOT NULL 
); 
INSERT INTO mytable(MONT,Value,ID) VALUES (201601,1,'X'); 
INSERT INTO mytable(MONT,Value,ID) VALUES (201601,1,'Y'); 
INSERT INTO mytable(MONT,Value,ID) VALUES (201601,1,'Y'); 
INSERT INTO mytable(MONT,Value,ID) VALUES (201602,1,'Z'); 
INSERT INTO mytable(MONT,Value,ID) VALUES (201603,1,'A'); 
INSERT INTO mytable(MONT,Value,ID) VALUES (201604,1,'B'); 
INSERT INTO mytable(MONT,Value,ID) VALUES (201605,1,'C'); 
INSERT INTO mytable(MONT,Value,ID) VALUES (201607,1,'E'); 
INSERT INTO mytable(MONT,Value,ID) VALUES (201607,10,'EE'); 
INSERT INTO mytable(MONT,Value,ID) VALUES (201607,100,'EEE'); 

クエリを1

SELECT MONT, RC, RC+ LAG(RC,3,0) OVER ( ORDER BY MONT)+ LAG(RC,2,0) OVER ( ORDER BY MONT) + LAG(RC,1,0) OVER ( ORDER BY MONT) AS RC_3M_PREC -- + COALESCE(LEAD(RC) OVER ( ORDER BY MONT),0) AS RC_3M 
FROM (SELECT MONT 
    , COUNT(*) RC 
    FROM mytable 
    GROUP BY MONT 
) A 

出力:

MONT  RC   RC_3M_PREC 
----------- ----------- ----------- 
201601  3   3 
201602  1   4 
201603  1   5 
201604  1   6 
201605  1   4 
201607  3   6 

それとも、提案したものを使用して(オプションROWS ... PRECEDING):

クエリ2:

SELECT MONT, RC 
    , COALESCE(SUM(RC) OVER (ORDER BY MONT ROWS BETWEEN 3 PRECEDING AND CURRENT ROW),0) AS RC_3M 
FROM (SELECT MONT 
    , COUNT(*) RC  
FROM mytable 
GROUP BY MONT 
) A 

出力:

MONT  RC   RC_3M 
----------- ----------- ----------- 
201601  3   3 
201602  1   4 
201603  1   5 
201604  1   6 
201605  1   4 
201607  3   6 
+0

@hhh別のクエリを追加しました。あなたが探していたものと同じです。 – etsa

+0

2番目のメソッドが機能しました。ありがとう+1 – hhh

0

あなただけの条件付きの集約を使用して、前の3ヶ月で行をカウントします。あなたは数ヶ月を列挙するための方法が必要なのか:

SELECT COUNT(*), 
     SUM(CASE WHEN yyyymm_counter <= 3 THEN 1 ELSE 0 END) 
FROM (SELECT md.*, 
      DENSE_RANK() OVER (ORDER BY MYMONTH DESC) as yyyymm_counter 
     FROM myData md 
    ) md; 

サブクエリのないもう一つの方法は、実際の日付に月の値に変換します。私はそれが文字列であると仮定しよう:

SELECT COUNT(*), 
     SUM(CASE WHEN DATEDIFF(month, CAST(MYMONTH + '01' as DATE), GETDATE()) <= 3 
       THEN 1 ELSE 0 
      END) 
FROM MyData; 

私は答えの出/を残してきました。 SQL Serverは整数の除算を行うので、値を非整数に変換しない限り、結果が得られない可能性があります(1.0を乗算するか、クエリで1の代わりに1.0を使用することを推奨します)。

+0

なぜこれは 'GETDATE()'を使用していますか? 'MyMONTH'が201601で、前の3ヶ月が201512,201511,201510であるとします。これは、2017-04-11 15 15:53:57.173に相当するGETDATE()でどのようにカウントされているのか分かりません。 – hhh

関連する問題