sql选择并比较最近值和第n个最近值,但在值重复超过三个月时排除
我使用下面的查询从按MeterNumber分组的表中选择最近值和第三个最近值。用户提供一个月和一天来确定返回的最高值 查询的目的是查看一个水表的水读数,看看它们在3个月内是否相同。如果是这样,则不会发生消耗,并且仪表可能损坏 我的问题是,我还想排除任何具有相同读数的第4、5、6号仪表。。。最近读取的日期,因为这些仪表可能未使用 任何帮助都将不胜感激!我对这一点很陌生,所以也许有一种更有效/更好的方法来实现这一点 我正在使用MS SQL 2012sql选择并比较最近值和第n个最近值,但在值重复超过三个月时排除,sql,sql-server,Sql,Sql Server,我使用下面的查询从按MeterNumber分组的表中选择最近值和第三个最近值。用户提供一个月和一天来确定返回的最高值 查询的目的是查看一个水表的水读数,看看它们在3个月内是否相同。如果是这样,则不会发生消耗,并且仪表可能损坏 我的问题是,我还想排除任何具有相同读数的第4、5、6号仪表。。。最近读取的日期,因为这些仪表可能未使用 任何帮助都将不胜感激!我对这一点很陌生,所以也许有一种更有效/更好的方法来实现这一点 我正在使用MS SQL 2012 SELECT MeterNumber, MAX
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
你在正确的轨道上。您可以在以下情况下使用maxcase。。。将以前的特定时段提取出来进行比较。像这样:
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
因此,如果当前读数等于上一次读取的第三次读数,您想显示结果,但如果当前读数等于上一次读取的第六次读数,则不想显示结果?@Joe-是的,这是正确的。谢谢!这是非常有用的,对我正在尝试做的事情很有用。我很感激你为我提供了一把小提琴和一个第二版本让我理解!
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