SQL 关于从两列中获取具有最大日期的记录的查询
SQL query regarding getting record having maximum date from two columns
我有一个 SQL 服务器 table 是这样的:
EMPs
Id Name DateOn DateOff
-------------------------------------------------
1 EMP1 2020-9-4 12:00 AM NULL
2 EMP1 2020-9-4 12:00 AM 2020-9-4 10:00 PM
3 EMP2 2020-7-4 12:00 AM NULL
4 EMP4 2020-7-4 12:00 AM 2020-9-4 10:00 PM
查询的另一个示例
DECLARE @EMP TABLE
(
Id INT,
NAME VARCHAR(200),
AlarmOnTimeStamp DATETIMEOFFSET,
AlarmOffTimeStamp DATETIMEOFFSET NULL
);
INSERT INTO @EMP VALUES(1,'Test1','2020-04-09 01:56:29.507',NULL)
INSERT INTO @EMP VALUES(2,'Test1','2020-04-09 01:56:29.507','2020-04-09 03:56:29.507')
INSERT INTO @EMP VALUES(3,'Test2','2020-04-09 01:56:29.507','2020-04-09 03:56:29.507')
select * from (
select *,
row_number() over (order by a.AlarmOffTimestamp desc) rn
from @EMP a
) a where rn = 1
enter image description here
Id
列是唯一的。
我想要一个 SQL 查询,要像上面的例子一样得到单条记录,我应该得到 Id => 2,3 和第 4 条记录;我很困惑如何将两列最大日期与 group by 语句一起使用。
您可以使用子查询进行过滤:
select e.*
from emps e
where e.id = (
select top (1) id
from emps e1
where e1.name = e.name
order by e1.dateon desc, e1.dateoff desc
)
不是很清楚你想要什么排序标准;这为您提供了具有最新 dateon
的记录;如果有关系,dateoff
用于打破它们。您可能希望根据您的具体要求调整子查询的 order by
子句。
此解决方案通常非常有效,即使是针对大型数据集也是如此。为了提高性能,您需要 (name, dateon, dateoff)
上的索引。您也可以尝试在索引的最后位置添加 id
,例如 (name, dateon, dateoff, id)
:这会使索引 覆盖 ,这意味着数据库可以执行仅通过查看索引的子查询。
示例数据:
Id | NAME | AlarmOnTimeStamp | AlarmOffTimeStamp
-: | :---- | :-------------------------- | :--------------------------
1 | Test1 | 2020-04-09 01:56:29.5070000 | null
2 | Test1 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000
3 | Test2 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000
结果:
Id | NAME | AlarmOnTimeStamp | AlarmOffTimeStamp
-: | :---- | :-------------------------- | :--------------------------
2 | Test1 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000
3 | Test2 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000
我认为简单的 row_number()
函数在这种情况下应该很好:
select * from (
select *,
row_number() over (order by DateOff desc) rn
from myTable
) a where rn = 1
在性能方面,您可以在用于排序和过滤结果集的列上定义索引,在这种情况下 DateOff
用于排序,因此它是索引的良好候选者。
我有一个 SQL 服务器 table 是这样的:
EMPs
Id Name DateOn DateOff
-------------------------------------------------
1 EMP1 2020-9-4 12:00 AM NULL
2 EMP1 2020-9-4 12:00 AM 2020-9-4 10:00 PM
3 EMP2 2020-7-4 12:00 AM NULL
4 EMP4 2020-7-4 12:00 AM 2020-9-4 10:00 PM
查询的另一个示例
DECLARE @EMP TABLE
(
Id INT,
NAME VARCHAR(200),
AlarmOnTimeStamp DATETIMEOFFSET,
AlarmOffTimeStamp DATETIMEOFFSET NULL
);
INSERT INTO @EMP VALUES(1,'Test1','2020-04-09 01:56:29.507',NULL)
INSERT INTO @EMP VALUES(2,'Test1','2020-04-09 01:56:29.507','2020-04-09 03:56:29.507')
INSERT INTO @EMP VALUES(3,'Test2','2020-04-09 01:56:29.507','2020-04-09 03:56:29.507')
select * from (
select *,
row_number() over (order by a.AlarmOffTimestamp desc) rn
from @EMP a
) a where rn = 1
enter image description here
Id
列是唯一的。
我想要一个 SQL 查询,要像上面的例子一样得到单条记录,我应该得到 Id => 2,3 和第 4 条记录;我很困惑如何将两列最大日期与 group by 语句一起使用。
您可以使用子查询进行过滤:
select e.*
from emps e
where e.id = (
select top (1) id
from emps e1
where e1.name = e.name
order by e1.dateon desc, e1.dateoff desc
)
不是很清楚你想要什么排序标准;这为您提供了具有最新 dateon
的记录;如果有关系,dateoff
用于打破它们。您可能希望根据您的具体要求调整子查询的 order by
子句。
此解决方案通常非常有效,即使是针对大型数据集也是如此。为了提高性能,您需要 (name, dateon, dateoff)
上的索引。您也可以尝试在索引的最后位置添加 id
,例如 (name, dateon, dateoff, id)
:这会使索引 覆盖 ,这意味着数据库可以执行仅通过查看索引的子查询。
示例数据:
Id | NAME | AlarmOnTimeStamp | AlarmOffTimeStamp -: | :---- | :-------------------------- | :-------------------------- 1 | Test1 | 2020-04-09 01:56:29.5070000 | null 2 | Test1 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000 3 | Test2 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000
结果:
Id | NAME | AlarmOnTimeStamp | AlarmOffTimeStamp -: | :---- | :-------------------------- | :-------------------------- 2 | Test1 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000 3 | Test2 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000
我认为简单的 row_number()
函数在这种情况下应该很好:
select * from (
select *,
row_number() over (order by DateOff desc) rn
from myTable
) a where rn = 1
在性能方面,您可以在用于排序和过滤结果集的列上定义索引,在这种情况下 DateOff
用于排序,因此它是索引的良好候选者。