用于返回每个Id

时间:2017-09-01 14:11:29

标签: sql sql-server

我试图编写一个查询(SQL服务器),它将为每个唯一ID的最接近日期值返回一个完整行。

例如,如果有20,000条记录和100条唯一ID,我希望为最接近日期值的每个唯一ID返回100条记录。

所有数据都在一个表中

以下我尝试了哪些不能工作

SELECT TOP(1) [Id]
      ,[Updated]
      ,[LoadTime]
      ,[Field4]
      ,[Field5]
      ,[Field6]
  FROM [dbo].[tblTempData]
WHERE [Updated] <= [LoadTime]

这只返回1条记录,而不是每条Id的单条记录。

SELECT DISTINCT [Id]
      ,[Updated]
      ,[LoadTime]
      ,[Field4]
      ,[Field5]
      ,[Field6]
  FROM [dbo].[tblTempData]
WHERE [Updated] <= [LoadTime]

这不起作用,因为没有其他字段是不同的所以我得到多个具有相同Id的记录

编辑 - 预期的示例数据和输出 enter image description here

4 个答案:

答案 0 :(得分:1)

取决于您对&#34;最近时间&#34;的定义。是,这是一种方法,它将为每个ID返回一个记录,其中LoadTime和Updated彼此最接近,这基本上是第一个更新的记录。

;with cte as(
SELECT [Id]
      ,[Updated]
      ,[LoadTime]
      ,[Field4]
      ,[Field5]
      ,[Field6]
      ,ClosestTime = datediff(second,LoadTime, Updated)
  FROM [dbo].[tblTempData]),

select
    [Id]
    ,[Updated]
    ,[LoadTime]
    ,[Field4]
    ,[Field5]
    ,[Field6]   
from
    cte
inner join
    (select Id, min(ClosestTime) dt
     from cte
     group by Id) cte2 on cte.Id = cte2.Id and cte2.dt = cte.ClosestTime

另一种方法是使用row_number()

;with cte as(
SELECT [Id]
        ,[Updated]
        ,[LoadTime]
        ,[Field4]
        ,[Field5]
        ,[Field6]
        ,RN = row_number() over (partition by Id order by LoadTime, Updated)
FROM [dbo].[tblTempData])

select 
    [Id]
    ,[Updated]
    ,[LoadTime]
    ,[Field4]
    ,[Field5]
    ,[Field6]
from
    cte
where
    RN = 1

答案 1 :(得分:1)

Sql-server有一个很好的快捷方式,可以通过row_number()

进行排序
offset.storage.file.filename=/tmp/connect.offsets  
offset.flush.interval.ms=120000 
offset.flush.timeout.ms=60000 
buffer.memory=100

答案 2 :(得分:0)

可能最好的方法是首先获取您正在寻找的最接近的LoadTime的记录,然后查询thoose记录(如果您有2条记录具有相同的LoadTime和Id,则这将为该Id生成2条记录)

SELECT * FROM [dbo].[tblTempData] a
INNER JOIN (
   SELECT Id,Max(LoadTime) FROM [dbo].[tblTempData]
     WHERE [Updated]<=[LoadTime]
     GROUP BY Id,Max(LoadTime)) b 
   ON (a.Id=b.Id AND a.LoadTime=b.LoadTime)

应该做的工作。

答案 3 :(得分:0)

怎么样,

SELECT
   [Id]
  ,[Updated]
  ,[LoadTime]
  ,[Field4]
  ,[Field5]
  ,[Field6]
FROM
(
    SELECT
       RANK() OVER (PARTITION BY [Id] ORDER BY DATEDIFF(ms, [Update], [LoadTime] ASC) [R]
      ,[Id]
      ,[Updated]
      ,[LoadTime]
      ,[Field4]
      ,[Field5]
      ,[Field6]
  FROM
       [dbo].[tblTempData]
) O
WHERE
    O.[R] = 1;

注意,将包括延迟相同毫秒数的行。如果您想要随机丢弃一个使用ROW_NUMBER()而不是。