如何为每个imei记录最大日期行

时间:2018-11-10 13:28:54

标签: sql sql-server tsql

我有一张桌子,里面有一些行。在这一行中,我需要为每个imei和每个日期(无时间)获取报告数据的所有行。但是总是有1个查询,请有人帮我吗?我对SQL不太熟悉。

我有这张桌子:

Id  Imei                CreationDate                  DeviceId
1   ProductionDevice299 2018-11-04 09:01:13.7202092   1
2   ProductionDevice299 2018-11-04 09:01:20.5318598   1
3   ProductionDevice299 2018-11-06 09:01:25.0101371   1
4   ProductionDevice299 2018-11-08 09:01:30.2557571   1
5   ProductionDevice299 2018-11-08 09:01:34.0354277   1
6   ProductionDevice299 2018-11-09 09:01:41.8190975   1
7   ProductionDevice299 2018-11-09 09:01:46.7797098   1

我想要这张桌子:

Id  Imei                CreationDate                  DeviceId
2   ProductionDevice299 2018-11-04 09:01:20.5318598   1
3   ProductionDevice299 2018-11-06 09:01:25.0101371   1
5   ProductionDevice299 2018-11-08 09:01:34.0354277   1
7   ProductionDevice299 2018-11-09 09:01:46.7797098   1

我当前的结果:

Id  Imei                CreationDate                  DeviceId
7   ProductionDevice299 2018-11-09 09:01:46.7797098   1

我当前的MS SQL查询:

SELECT 
    [Extent1].[Id] AS [id], 
    [Extent1].[Imei] AS [imei], 
    [Extent1].[CreationDate] AS [lastSeenOnline],  
    [Extent1].[DeviceId] AS [deviceId]
    FROM [dbo].[DeviceHistory] AS [Extent1]

    INNER JOIN (
        SELECT [Imei], max([CreationDate]) as MaxDate
        FROM [dbo].[DeviceHistory]
        GROUP BY [Imei]
    ) [Extent2] on [Extent1].[Imei] = [Extent2].[Imei] and [Extent1].[CreationDate] = [Extent2].MaxDate

2 个答案:

答案 0 :(得分:0)

您需要按日期(无时间)分组:

SELECT 
    [Extent1].[Id] AS [id], 
    [Extent1].[Imei] AS [imei], 
    [Extent1].[CreationDate] AS [lastSeenOnline],  
    [Extent1].[DeviceId] AS [deviceId]
    FROM [dbo].[DeviceHistory] AS [Extent1]

    INNER JOIN (
        SELECT [Imei], max([CreationDate]) as MaxDate
        FROM [dbo].[DeviceHistory]
        GROUP BY [Imei]
          ,CAST([CreationDate] AS DATE) -- for each day
    ) [Extent2]
   on [Extent1].[Imei] = [Extent2].[Imei]
  and [Extent1].[CreationDate] = [Extent2].MaxDate

铸造为日期会删除时间部分。

您还可以应用行号,将“分组依据”条件移至“分区依据”:

with cte as 
 (
   SELECT *,
      row_number()
      over (partititon by [Imei], CAST([CreationDate] AS DATE)
            order by CreationDate) as rn
   FROM [dbo].[DeviceHistory] AS [Extent1]
 )
select id, 
   imei, 
   CreationDate AS lastSeenOnline, 
   DeviceId
from cte
where rn = 1

对于性能测试,您还可以尝试MIN:

with cte as 
 (
   SELECT *,
      min(CreationDate)
      over (partititon by [Imei], CAST([CreationDate] AS DATE)) as minDate
   FROM [dbo].[DeviceHistory] AS [Extent1]
 )
select id, 
   imei, 
   CreationDate AS lastSeenOnline, 
   DeviceId
from cte
where CreationDate = minDate

答案 1 :(得分:0)

只需使用聚合:

SELECT MIN(dh.id) as id, dh.Imei, MIN(dh.CreationDate) as CreationDate,
       dh.DeviceId
FROM DeviceHistory dh
GROUP BY dh.Imei, dh.DeviceId,
         CONVERT(DATE, dh.CreationDate);

此版本(合理)假设idcreationdate一起增加。

如果没有,那么我推荐row_number()

SELECT dh.*
FROM (SELECT dh.*,
             ROW_NUMBER() OVER (PARTITION BY dh.Imei, CONVERT(DATE, dh.CreationDate) ORDER BY dh.CreationDate) as seqnum
      FROM DeviceHistory dh
     ) dh
WHERE seqnum = 1;