T-SQL查询以选择具有更接近时间戳的值

时间:2017-06-06 11:52:53

标签: sql-server tsql

我正在尝试根据表A中的ID进行查询,以显示表P中距离具有相同TimestampLocal列广告表A的最近行。

我设法做到了:

 IF(A.Generated - P.Local) >= 0 THEN
       select P.Location where P.Local = A.Generated + MIN(A.Generated - P.Local)
    ELSE
       select P.Location where P.Local = A.Generated + MAX(A.Generated - P.Local)

我正试图从表P中获取价值。

IF (select datediff(second, a.Generated,p.Local) from A a inner join P p on a.VId=p.VId where a.Id = 830566) >=0
select Location from P where Local = dateadd(millisecond,(select Min(datediff(second, a.Generated,p.Local)) from A a inner join P p on a.VId=p.VId where a.Id=830566), 
(select Generated from A where Id=830566))

ELSE

select Location from P where Local =dateadd(second,(select Max(datediff(millisecond, a.Generated,p.Local)) from A a inner join P p on a.VId=p.VId where a.Id=830566), 
(select Generated from A where Id=830566))

但是我得到了错误:

  

子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。

  

datediff函数导致溢出。分隔两个日期/时间实例的日期部分数量太大。尝试使用具有不太精确的日期部分的datediff。

但是我不知道为什么:(根据表A Id,可以从表P得到最接近的行?如果P中有多行,则使用相同的TimeStampLocal来获取第一行?

更新

表A:

Id       Generated                            VId
830566 | 2017-06-04 10:38:22.2000000 -07:00 | 5635
830567 | 2017-06-04 10:38:45.1000000 -07:00 | 5634
830568 | 2017-06-04 10:31:59.6000000 -07:00 | 5638

表P:

VId    Local                                Location
5638 | 2017-06-04 10:26:17.9000000 -07:00 | 0xE6
5638 | 2017-06-04 10:31:48.6000000 -07:00 | 0X7F
5638 | 2017-06-04 10:32:48.7000000 -07:00 | 0x3C
5634 | 2017-06-04 10:31:48.6000000 -07:00 | 0xA6

例如:对于表A中的Id 830568(作为参数接收) - VId 5638,我应该从表P得到最接近的行,其中最接近的本地时间和相同的VId,在此case第二个2017-06-04 10:31:48.6000000 -07:00,对于P中的这一行,我需要获取位置:0X7F

1 个答案:

答案 0 :(得分:1)

这应该这样做。如果你想要最近的时间没有"过去"然后删除ABS()函数周围的datediff()并取消注释连接条件。

declare @TableA table (Id int, [Generated] datetime2, VId int)

declare @TableB table (VId int, [Local] datetime2, [Location] varchar(64))

insert into @TableA
values
(830566,'2017-06-04 10:38:22.2000000 -07:00',5635),
(830567,'2017-06-04 10:38:45.1000000 -07:00',5634),
(830568,'2017-06-04 10:31:59.6000000 -07:00 ',5638)

insert into @TableB values

(5638,'2017-06-04 10:26:17.9000000 -07:00','0xE6'),
(5638,'2017-06-04 10:31:48.6000000 -07:00','0X7F'),
(5638,'2017-06-04 10:32:48.7000000 -07:00','0x3C'),
(5634,'2017-06-04 10:31:48.6000000 -07:00','0xA6')


;with cte as(
select
    a.Id
    ,a.VId
    ,a.Generated
    ,b.Local
    ,b.Location
    ,ABS(DATEDIFF(second,a.Generated,b.Local)) as TD
from 
    @TableA a
inner join 
    @TableB b on
    b.VId = a.VId)
    --and b.local < a.Generated

select
    c.Id
    ,c.VId
    ,c.Location
from 
    cte c
    inner join
        (select ID, min(TD) TD
         from cte
         group by ID) c2 on c2.Id = c.Id and c2.TD = c.TD