我使用以下查询从按MeterNumber分组的表中选择最近和最近的第3个值。用户提供一个月和日,确定返回的最高值。
查询的目的是查看仪表的水读数,并查看它们在3个月内是否相同。如果是这样,就不会发生消耗,仪表可能会损坏。
我的问题是,我还想排除任何对第4,第5,第6,......最近阅读日期有相同读数的仪表,因为这些仪表很可能未被使用。
任何帮助将不胜感激!我对此非常陌生,所以也许有更有效/更好的方法来实现这一目标。
我正在使用MS SQL 2012。
SELECT
MeterNumber,
MAX(WaterRead) AS CurrentRead,
MAX(ReadDate) AS CurrentReadDate,
MIN(WaterRead) AS nthLastRead,
MIN(ReadDate) AS nthLastReadDate
From
(SELECT MeterNumber, ReadDate, WaterRead
FROM (
SELECT MeterNumber, ReadDate, WaterRead, Rank() over (Partition BY MeterNumber ORDER BY ReadDate DESC ) AS myRank
FROM WaterReads
) WaterReads WHERE myRank <= 3 ) a
Group By MeterNumber
Having MAX(WaterRead) - MIN(WaterRead) = 0 AND MAX(WaterRead) != 0 AND MIN(WaterRead) != 0 AND MIN(ReadDate) <> MAX(ReadDate)
AND MONTH(MAX(ReadDate)) = 6 AND DAY(MAX(ReadDate)) = 25
ORDER BY MeterNumber, CurrentReadDate
返回:
MeterNumber CurrentRead CurrentReadDate nthLastRead nthLastReadDate
80021139 12103 2013-06-25 12103 2013-04-24
80029512 5347 2013-06-25 5347 2013-04-24
80038245 304304 2013-06-25 304304 2013-04-24
80044119 46250 2013-06-25 46250 2013-04-24
80048357 6707 2013-06-25 6707 2013-04-24
答案 0 :(得分:0)
你走在正确的轨道上。您可以使用max(大于......的情况)来抽取特定的前一个时段进行比较。像这样:
SELECT
meternumber,
MAX(CASE WHEN myrank = 1 THEN readdate ELSE NULL END) curr_date,
MAX(CASE WHEN myrank = 1 THEN waterread ELSE NULL END) curr_read,
MAX(CASE WHEN myrank = 4 THEN readdate ELSE NULL END) ago3_date,
MAX(CASE WHEN myrank = 4 THEN waterread ELSE NULL END) ago3_read,
MAX(CASE WHEN myrank = 7 THEN readdate ELSE NULL END) ago6_date,
MAX(CASE WHEN myrank = 7 THEN waterread ELSE NULL END) ago6_read
FROM
(
SELECT MeterNumber,
ReadDate,
WaterRead,
Rank() over (Partition BY MeterNumber ORDER BY ReadDate DESC ) AS myRank
FROM WaterReads
WHERE readdate <= '20130625'
) AS a
GROUP BY
meternumber
HAVING
MAX(CASE WHEN myrank = 1 THEN waterread ELSE NULL END) = MAX(CASE WHEN myrank = 4 THEN waterread ELSE NULL END)
AND MAX(CASE WHEN myrank = 1 THEN waterread ELSE NULL END) > MAX(CASE WHEN myrank = 7 THEN waterread ELSE NULL END)
AND MAX(CASE WHEN myrank = 4 THEN waterread ELSE NULL END) > 0
或者,更容易阅读,但有一个额外的子查询:
SELECT
meternumber,
curr_date,
curr_read,
ago3_date,
ago3_read,
ago6_date,
ago6_read
FROM
(
SELECT
meternumber,
MAX(CASE WHEN myrank = 1 THEN readdate ELSE NULL END) curr_date,
MAX(CASE WHEN myrank = 1 THEN waterread ELSE NULL END) curr_read,
MAX(CASE WHEN myrank = 4 THEN readdate ELSE NULL END) ago3_date,
MAX(CASE WHEN myrank = 4 THEN waterread ELSE NULL END) ago3_read,
MAX(CASE WHEN myrank = 7 THEN readdate ELSE NULL END) ago6_date,
MAX(CASE WHEN myrank = 7 THEN waterread ELSE NULL END) ago6_read
FROM
(
SELECT MeterNumber,
ReadDate,
WaterRead,
Rank() over (Partition BY MeterNumber ORDER BY ReadDate DESC ) AS myRank
FROM WaterReads
WHERE readdate <= '20130625'
) AS a
GROUP BY
meternumber
) AS b
WHERE
curr_read = ago3_read
AND curr_read > ago6_read
AND ago3_read > 0