web-dev-qa-db-ja.com

過去3か月の各月の最大値を適切に見つける

過去3か月のIDのデータを取得するクエリがあります。 3か月ごとに最高の値が得られるように調整する必要があります。集約関数MAXでいくつかのことを試しましたが、どこにも行きません。

私は過去数ヶ月のそれぞれの最大値を取得しようとしています...

以下は、現在日付(asc)でソートされたクエリのデータです。

 ID日付値
 12410 2017年3月1日12:17 0.000178 
 12410 2017年10月10日11:36 0.000186 
 12410 2017年1月17日11 :27 0.000189 
 12410 2017/01/24 13:09 0.000182 
 12410 01/31/2017 10:37 0.000169 
 12410 2017年2月7日11:03 0.000214 
 12410 2017年2月14日11:52 0.000176 
 12410 2017年2月21日10:51 0.000200 
 12410 02/28/2017 12:29 0.000194 
 12410 03 2017年7月7日08:39 0.000206 

これがクエリです:

 AnalysisIDを「ID」、AnalysisDateTimeを「日付」、AnalysisValueを「値」としてAnalysisValueTbl 
から選択します
 AnalysisID = 12410およびDatePart(m、AnalysisDateTime)= DatePart(m 、DateAdd(m、-3、getdate()))
およびDatePart(yyyy、AnalysisDateTime)= DatePart(yyyy、DateAdd(m、-3、getdate()))
または
 AnalysisID = 12410およびDatePart(m、AnalysisDateTime)= DatePart(m、DateAdd(m、-2、getdate()))
およびDatePart(yyyy、AnalysisDateTime)= DatePart(yyyy、DateAdd(m 、-2、getdate()))
または
 AnalysisID = 12410およびDatePart(m、AnalysisDateTime)= DatePart(m、DateAdd(m、-1、getdate()))
およびDatePart(yyyy、AnalysisDateTime)= DatePart(yyyy、DateAdd(m、-1、getdate()))
 order by AnalysisValue desc 
4
Emperor1951

SQL Serverの場合、次のようなことができます。

DECLARE @t TABLE (Id INT, DateVal DATETIME, ValueVal DECIMAL(18, 9));

INSERT @t ( Id, DateVal, ValueVal )
SELECT Id, DateVal, ValueVal
FROM (
    VALUES 
    (12410,   '01/03/2017 12:17',    0.000178),
    (12410,   '01/10/2017 11:36',    0.000186),
    (12410,   '01/17/2017 11:27',    0.000189),
    (12410,   '01/24/2017 13:09',    0.000182),
    (12410,   '01/31/2017 10:37',    0.000169),
    (12410,   '02/07/2017 11:03',    0.000214),
    (12410,   '02/14/2017 11:52',    0.000176),
    (12410,   '02/21/2017 10:51',    0.000200),
    (12410,   '02/28/2017 12:29',    0.000194),
    (12410,   '03/07/2017 08:39',    0.000206)
) x (Id, DateVal, ValueVal);

SELECT  DATEPART(MONTH, t.DateVal) AS [DateVal],
        MAX(t.ValueVal) AS MaxVal
FROM @t AS t
WHERE t.DateVal >= DATEADD(MONTH, -3, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
GROUP BY DATEPART(MONTH, t.DateVal);

更新されたWHERE句:日付のフラット化は奇妙であり、以前のクエリでは、今日の日付から3か月差し引いた日付が得られました。 3か月前の最初の状態に戻るには、いくつかのトリックを変える必要があります。

SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0) AS [First Of This Month],
       DATEADD(MONTH, -3, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)) AS [First Of Three Months Ago]

これを理解するために少し時間をかけるか、それを行う方法のチートシートを手元に置いておくと、ひどい日付計算を覚える必要がなくなります;)

9
Erik Darling