返回满足sql条件的最后一行

时间:2015-04-15 20:14:04

标签: sql select group-by max

我有两张桌子:

仪表

ID         SerialNumber
=======================
1          ABC1
2          ABC2
3          ABC3
4          ABC4
5          ABC5
6          ABC6

RegisterLevelInformation

ID         MeterID    ReadValue    Consumption  PreviousReadDate    ReadType
============================================================================
1          1          250          250          1 jan 2015          EST
2          1          550          300          1 feb 2015          ACT
3          1          1000         450          1 apr 2015          EST
4          2          350          350          1 jan 2015          EST
5          2          850          500          1 feb 2015          ACT
6          2          1000         150          1 apr 2015          ACT
7          3          1500         1500         1 jan 2015          EST
8          3          2500         1000         1 mar 2015          EST
9          3          5000         2500         4 apr 2015          EST
10         4          250          250          1 jan 2015          EST
11         4          550          300          1 feb 2015          ACT
12         4          1000         450          1 apr 2015          EST
13         5          350          350          1 jan 2015          ACT
14         5          850          500          1 feb 2015          ACT
15         5          1000         150          1 apr 2015          ACT
16         6          1500         1500         1 jan 2015          EST
17         6          2500         1000         1 mar 2015          EST
18         6          5000         2500         4 apr 2015          EST

我正在尝试按米序列分组并返回每个仪表的最后实际读取日期,但我不确定如何完成此操作。这是我到目前为止的sql:

select a.SerialNumber, ReadTypeCode, MAX(PreviousReadDate) from Meter as a
left join RegisterLevelInformation as b on a.MeterID = b.MeterID
where ReadType = 'ACT'
group by a.SerialNumber,b.ReadTypeCode, PreviousReadDate
order by a.SerialNumber

我似乎无法使MAX函数在仅返回最新的实际读取行时生效,并返回所有日期,并且多次显示相同的仪表序列。

如果我使用以下sql:

select a.SerialNumber, count(*) from Meter as a
left join RegisterLevelInformation as b on a.MeterID = b.MeterID
group by a.SerialNumber
order by a.SerialNumber

然后每个序列只显示一次。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

就像@PaulGriffin在评论中所说,您需要从PreviousReadDate条款中删除GROUP BY列。

您为什么遇到这种行为?

基本上,您为每个不同的值对选择的分区(SerialNumber,ReadTypeCode,PreviousReadDate)会打印SerialNumber, ReadTypeCode, MAX(PreviousReadDate)。由于您将MAX()函数应用于包含此列的分区的每一行,因此您只需对一个值使用聚合函数 - 因此MAX()的输出将等于没有它的那个。

您想要实现的目标

为每对MAX获取PreviousReadDate(SerialNumber,ReadTypeCode)。所以这就是你的GROUP BY条款应该包含的内容。

select a.SerialNumber, ReadTypeCode, MAX(PreviousReadDate) from Meter as a
left join RegisterLevelInformation as b on a.MeterID = b.MeterID
where ReadType = 'ACT'
group by a.SerialNumber,b.ReadTypeCode
order by a.SerialNumber

是否是您想要的正确的SQL查询。

差异示例

ID         MeterID    ReadValue    Consumption  PreviousReadDate    ReadType
============================================================================
1          1          250          250          1 jan 2015          EST
2          1          550          300          1 feb 2015          ACT
3          1          1000         450          1 apr 2015          EST

如果您通过3列分组应用查询,您将获得结果:

SerialNumber | ReadTypeCode | PreviousReadDate
  ABC1       |    EST       | 1 jan 2015 -- which is MAX of 1 value (1 jan 2015)
  ABC1       |    ACT       | 1 feb 2015
  ABC1       |    EST       | 1 apr 2015

但是当你只按SerialNumber,ReadTypeCode分组时,它会产生结果(考虑我发布的样本数据):

SerialNumber | ReadTypeCode | PreviousReadDate
  ABC1       |    EST       | 1 apr 2015 -- which is MAX of 2 values (1 jan 2015, 1 apr 2015)
  ABC1       |    ACT       | 1 feb 2015 -- which is MAX of 1 value (because ReadTypeCode is different from the row above

第二次查询的说明

在这个查询中 - 你确实是对的 - 每个序列只显示一次。

select a.SerialNumber, count(*) from Meter as a
left join RegisterLevelInformation as b on a.MeterID = b.MeterID
group by a.SerialNumber
order by a.SerialNumber

但是,如果您通过更多列添加分组(您在第一个查询中已经完成了 - 自己尝试),此查询会产生奇怪的结果。

答案 1 :(得分:1)

您需要从Group By子句中删除PreviousReadDate。 这是您的查询应该是这样的:

select a.SerialNumber, ReadTypeCode, MAX(PreviousReadDate) from Meter as a
left join RegisterLevelInformation as b on a.MeterID = b.MeterID
where ReadType = 'ACT'
group by a.SerialNumber,b.ReadTypeCode
order by a.SerialNumber

要了解在提及多列时group by子句如何工作,请点击以下链接:Using group by on multiple columns

您将了解查询的错误以及返回所有日期的原因,并且多次显示相同的仪表序列。 祝好运! 奖励! :)