2017-08-16 28 views
0

SQL Serverでは、私は2つの日付列xとy列を持っています。毎年。SQL - 2つの日付の間の頻度(毎月、四半期、毎年)

私は自分自身を試してみましたが、正しくない

コードのようだ:誰も私がこれを正しくコーディングする助けることができる場合、私は感謝

CASE WHEN ROUND(DATEDIFF(d, ISNULL(RV.[x], ''), ISNULL(RV.[y], ''))/30.0, 1) <= 1 THEN 'MONTHLY'  
    WHEN ROUND(DATEDIFF(d, ISNULL(RV.[x], ''), ISNULL(RV.[y], ''))/30.0, 1) BETWEEN 1 AND 3 THEN 'QUARTERLY' 
    ELSE 'ANNUALLY' 
END FREQUENCY 

あなたは、あなたがDATEDIFFは時々負の値を返すことに気付くだろう日付のためのいくつかのNULL値を持つモックデータ上でそれを実行したい場合

+0

それはあなたの定義に依存し、どのようにあなたが特別な例を占めています。例diff> = 30日は毎月、diff> = 365日は毎年ですが、これは31日の最初と最後の日とうるう年に失敗する可能性があります。追加するルールを拡張することができ、その日付の月/年は同じではありません。それはSQLの質問ではなく、必要なものです – jean

+0

'Day'が任意の周波数で同じになることが確かであれば、解決策は' Month'(と 'Year' )の日付の部分。 実際、日が+/- 3日ぐらいになっても、計算を実行して日を無視することができます。 ... '2017-01-13'と '2017-04-13'の間の頻度は '4 - 1 = 3'(四半期)です。 –

答えて

0

を高く評価し、あなたと多くをありがとうございます。
その理由は、間違った理由でCASEが "MONTHLY"を返すことになります。

ISNULLをしないでください。そうすれば、DATEDIFFはNULLを返し、「ANNUALLY」に評価されます。

また、f.eでDATEDIFFを取得することもできます。あなたの質問を簡単にすることができます。

declare @TestTable table (x date, y date); 

declare @y date = '2017-08-15'; 

insert into @TestTable (x,y) values 
(dateadd(day,-10,@y),@y), 
(dateadd(day,-30,@y),@y), 
(dateadd(day,-60,@y),@y), 
(dateadd(day,-240,@y),@y), 
(null,@y), 
(dateadd(month,-2,@y),null); 

select RV.*, 
/* 
DATEDIFF(day, RV.[x], RV.[y]) as monthdiff, 
DATEDIFF(month, RV.[x], RV.[y]) as monthdiff, 
DATEDIFF(quarter, RV.[x], RV.[y]) as quarterdiff, 
DATEDIFF(year, RV.[x], RV.[y]) as yeardiff, 
*/ 
CASE 
WHEN DATEDIFF(month, RV.[x], RV.[y]) = 0 THEN 'MONTHLY' 
WHEN DATEDIFF(quarter, RV.[x], RV.[y]) = 0 THEN 'QUARTERLY' 
WHEN DATEDIFF(year, RV.[x], RV.[y]) = 0 THEN 'ANNUALLY' 
ELSE 'ANNUALLY?' 
END FREQUENCY 
from @TestTable RV; 

戻り値:

x   y   FREQUENCY 
---------- ---------- ---------- 
2017-08-05 2017-08-15 MONTHLY 
2017-07-16 2017-08-15 QUARTERLY 
2017-06-16 2017-08-15 ANNUALLY 
2016-12-18 2017-08-15 ANNUALLY? 
NULL  2017-08-15 ANNUALLY? 
2017-06-15 NULL  ANNUALLY? 

もチェックこのテストSQLの結果:

select RV.*, 
DATEDIFF(day, x, y) as daydiff, 
DATEDIFF(month, x, y) as monthdiff, 
DATEDIFF(quarter, x, y) as quarterdiff, 
case when DATEDIFF(quarter, RV.[x], RV.[y]) = 0 then 'yes' else 'no' end as same_quarter 
from (values 
('2017-01-15','2017-03-31'), 
('2017-01-15','2017-04-01') 
) as RV(x,y); 
+0

迅速な回答をいただきありがとうございます。面白い答え。非常に感謝 –

+0

@SatyenGotecha申し訳ありませんが、論理的な間違いを犯しました。更新版を参照してください。 – LukStorms

+0

@LukStorms論理的には、比較文は意味をなさない。しかし、私はそれがOPからのキャリーオーバーであることを認識しています。 「... DATEDIFF(月、RV。[x]、RV。[y])= 1次に、DATEDIFF(月、RV。[x]、 RV。[y])= 3 THEN 'QUARTERLY' ... 'そして、 'year'の差異が1であれば、' YEARLY'となります。 –

関連する問題