【问题标题】:T-SQL query to select values with closer timestampT-SQL 查询以选择具有更接近时间戳的值
【发布时间】:2017-06-06 11:52:53
【问题描述】:

我正在尝试基于表 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 与不太精确的 datepart 一起使用。

但我不知道为什么 :( 可以根据表 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,在这种情况下是第二个2017-06-04 10:31:48.6000000 -07:00,对于来自 P 的这一行,我需要获取位置:0X7F

【问题讨论】:

  • 你能发布一些示例数据(作为插入...)和预期值(作为文本)吗?
  • @etsa 我已经进行了必要的更新
  • 最接近的没有超过或最接近的时期?如果 VId 5638 有一个 10:32:00 应该返回还是仍然是您声明的值呢?
  • 如果 VId 5438 是 10:32:00 而不是 10:31:59,它应该返回 10:32:00,因为那是最接近表 A 中的时间。最接近的时间不能t 是开始的准确小时和分钟

标签: sql-server tsql


【解决方案1】:

应该这样做。如果您想要最接近的时间而不“越过”,请移除 datediff() 函数周围的 ABS() 并取消注释掉连接条件。

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

【讨论】:

  • 完美运行!非常感谢您的回答! :) 起来!
  • 你也是! :)再次感谢!
  • 如果该准确度级别发挥作用,可能需要将秒更改为毫秒。只是一个想法。
猜你喜欢
  • 2018-03-18
  • 2014-12-20
  • 1970-01-01
  • 2013-03-31
  • 1970-01-01
  • 2016-10-20
  • 2021-10-14
  • 1970-01-01
相关资源
最近更新 更多