select 每个实体的前 N 条记录
select top N records for each entity
我有一个 table
如下 -
ID | Reported Date | Device_ID
-------------------------------------------
1 | 2016-03-09 09:08:32.827 | 1
2 | 2016-03-08 09:08:32.827 | 1
3 | 2016-03-08 09:08:32.827 | 1
4 | 2016-03-10 09:08:32.827 | 2
5 | 2016-03-05 09:08:32.827 | 2
现在,我想要一个基于 date column
的 top 1
row
每个 device_ID
预期输出
ID | Reported Date | Device_ID
-------------------------------------------
1 | 2016-03-09 09:08:32.827 | 1
4 | 2016-03-10 09:08:32.827 | 2
我正在使用 SQL Server 2008 R2
。我可以去写 Stored Procedure
来处理它,但想用简单的查询来完成。
******************编辑***************************
'Felix Pamittan' 的回答效果很好,但 'N' 只需将其更改为
SELECT
Id, [Reported Date], Device_ID
FROM (
SELECT *,
Rn = ROW_NUMBER() OVER(PARTITION BY Device_ID ORDER BY [ReportedDate] DESC)
FROM tbl
)t
WHERE Rn >= N
他在评论中提到了这一点,想将其添加到问题中,以免有人错过。
使用ROW_NUMBER
:
SELECT
Id, [Reported Date], Device_ID
FROM (
SELECT *,
Rn = ROW_NUMBER() OVER(PARTITION BY Device_ID ORDER BY [ReportedDate] DESC)
FROM tbl
)t
WHERE Rn = 1
如果您不能使用分析函数,例如因为您的应用层不允许,那么您可以尝试以下使用子查询得出答案的解决方案:
SELECT t1.ID, t2.maxDate, t1.Device_ID
INNER JOIN
(
SELECT Device_ID, MAX([Reported Date]) AS maxDate
FROM yourTable
GROUP BY Device_ID
) t2
ON t1.Device_ID = t2.Device_ID AND t1.[Reported Date] = t2.maxDate
您也可以尝试使用 CTE
With DeviceCTE AS
(SELECT *, ROW_NUMBER() OVER(PARTITION BY Device_ID ORDER BY [Reported Date] DESC) AS Num
FROM tblname)
SELECT Id, [Reported Date], Device_ID
From DeviceCTE
Where Num = 1
Select * from DEVICE_TABLE D
where [Reported Date] = (Select Max([Reported Date]) from DEVICE_TABLE where Device_ID = D.Device_ID)
应该可以解决问题,假设 "top 1 row based on date column" 意味着您想要 select 每个 Device_ID 的最新报告日期?
至于你的标题,select 每个 Device_ID
的前 5 行
Select * from DEVICE_TABLE D
where [Reported Date] in (Select top 5 [Reported Date] from DEVICE_TABLE D where Device_ID = D.Device_ID)
order by Device_ID, [Reported Date] desc
将为您提供每个设备 ID 的前 5 个最新报告。
如果您的数据不符合顺序,您可能需要整理出前 5 个日期...
再次没有分析功能,您可以使用 CROSS APPLY :
DECLARE @tbl TABLE(Id INT,[Reported Date] DateTime , Device_ID INT)
INSERT INTO @tbl
VALUES
(1,'2016-03-09 09:08:32.827',1),
(2,'2016-03-08 09:08:32.827',1),
(3,'2016-03-08 09:08:32.827',1),
(4,'2016-03-10 09:08:32.827',2),
(5,'2016-03-05 09:08:32.827',2)
SELECT r.*
FROM ( SELECT DISTINCT Device_ID FROM @tbl ) d
CROSS APPLY ( SELECT TOP 1 *
FROM @tbl t
WHERE d.Device_ID = t.Device_ID ) r
可以轻松修改以支持N条记录。
感谢 wBob 回答了这个问题 here
我有一个 table
如下 -
ID | Reported Date | Device_ID
-------------------------------------------
1 | 2016-03-09 09:08:32.827 | 1
2 | 2016-03-08 09:08:32.827 | 1
3 | 2016-03-08 09:08:32.827 | 1
4 | 2016-03-10 09:08:32.827 | 2
5 | 2016-03-05 09:08:32.827 | 2
现在,我想要一个基于 date column
的 top 1
row
每个 device_ID
预期输出
ID | Reported Date | Device_ID
-------------------------------------------
1 | 2016-03-09 09:08:32.827 | 1
4 | 2016-03-10 09:08:32.827 | 2
我正在使用 SQL Server 2008 R2
。我可以去写 Stored Procedure
来处理它,但想用简单的查询来完成。
******************编辑***************************
'Felix Pamittan' 的回答效果很好,但 'N' 只需将其更改为
SELECT
Id, [Reported Date], Device_ID
FROM (
SELECT *,
Rn = ROW_NUMBER() OVER(PARTITION BY Device_ID ORDER BY [ReportedDate] DESC)
FROM tbl
)t
WHERE Rn >= N
他在评论中提到了这一点,想将其添加到问题中,以免有人错过。
使用ROW_NUMBER
:
SELECT
Id, [Reported Date], Device_ID
FROM (
SELECT *,
Rn = ROW_NUMBER() OVER(PARTITION BY Device_ID ORDER BY [ReportedDate] DESC)
FROM tbl
)t
WHERE Rn = 1
如果您不能使用分析函数,例如因为您的应用层不允许,那么您可以尝试以下使用子查询得出答案的解决方案:
SELECT t1.ID, t2.maxDate, t1.Device_ID
INNER JOIN
(
SELECT Device_ID, MAX([Reported Date]) AS maxDate
FROM yourTable
GROUP BY Device_ID
) t2
ON t1.Device_ID = t2.Device_ID AND t1.[Reported Date] = t2.maxDate
您也可以尝试使用 CTE
With DeviceCTE AS
(SELECT *, ROW_NUMBER() OVER(PARTITION BY Device_ID ORDER BY [Reported Date] DESC) AS Num
FROM tblname)
SELECT Id, [Reported Date], Device_ID
From DeviceCTE
Where Num = 1
Select * from DEVICE_TABLE D
where [Reported Date] = (Select Max([Reported Date]) from DEVICE_TABLE where Device_ID = D.Device_ID)
应该可以解决问题,假设 "top 1 row based on date column" 意味着您想要 select 每个 Device_ID 的最新报告日期?
至于你的标题,select 每个 Device_ID
的前 5 行Select * from DEVICE_TABLE D
where [Reported Date] in (Select top 5 [Reported Date] from DEVICE_TABLE D where Device_ID = D.Device_ID)
order by Device_ID, [Reported Date] desc
将为您提供每个设备 ID 的前 5 个最新报告。 如果您的数据不符合顺序,您可能需要整理出前 5 个日期...
再次没有分析功能,您可以使用 CROSS APPLY :
DECLARE @tbl TABLE(Id INT,[Reported Date] DateTime , Device_ID INT)
INSERT INTO @tbl
VALUES
(1,'2016-03-09 09:08:32.827',1),
(2,'2016-03-08 09:08:32.827',1),
(3,'2016-03-08 09:08:32.827',1),
(4,'2016-03-10 09:08:32.827',2),
(5,'2016-03-05 09:08:32.827',2)
SELECT r.*
FROM ( SELECT DISTINCT Device_ID FROM @tbl ) d
CROSS APPLY ( SELECT TOP 1 *
FROM @tbl t
WHERE d.Device_ID = t.Device_ID ) r
可以轻松修改以支持N条记录。
感谢 wBob 回答了这个问题 here