基于最近时间戳联接两个表的SQL查询

基于最近时间戳联接两个表的SQL查询,sql,sql-server,sql-server-2008,join,timestamp,Sql,Sql Server,Sql Server 2008,Join,Timestamp,我需要从dbo.transaction(所有用户的事务,每个用户有多个事务)中检索时间戳最接近dbo.bal中时间的记录(每个用户的当前余额详细信息,每个用户只有一条记录) 即,结果记录应等于dbo.bal中的记录数 在这里,我尝试了下面的查询,只得到了比dbo.bal中的时间短的记录。但有些记录的时间戳大于并最接近dbo.bal.time SELECT dbo.bal.uid, dbo.bal.userId, dbo.bal.balance, dbo.

我需要从dbo.transaction(所有用户的事务,每个用户有多个事务)中检索时间戳最接近dbo.bal中时间的记录(每个用户的当前余额详细信息,每个用户只有一条记录)

即,结果记录应等于dbo.bal中的记录数

在这里,我尝试了下面的查询,只得到了比dbo.bal中的时间短的记录。但有些记录的时间戳大于并最接近dbo.bal.time

SELECT dbo.bal.uid,
       dbo.bal.userId,
       dbo.bal.balance,
       dbo.bal.time,
  (SELECT TOP 1 transactionBal
   FROM dbo.transaction
   WHERE TIMESTAMP <= dbo.bal.time
   ORDER BY TIMESTAMP DESC) AS newBal
FROM dbo.bal
WHERE dbo.bal.time IS NOT NULL
ORDER BY dbo.bal.time DESC
结果应该是

| Id | userId   | balance | time                    | credit | transactionBal 
-----------------------------------------------------------------------------
| 1  | 101      | 500     | 2012-01-13 05:34:45.645 | 200    | 300
| 2  | 102      | 700     | 2012-01-01 08:18:34.685 | 200    | 200
| 3  | 103      | 300     | 2012-01-15 02:16:34.672 | 300    | 300

请帮帮我。。任何帮助都必须感谢…谢谢你

如果你发布你的表格结构会很有帮助,但是

  • 我认为您的内部查询需要一个连接条件。(这实际上不在你的问题中)

  • 内部查询中的
    orderby
    子句可以是
    ABS(TIMESTAMP-DB0.BAL.TIME)
    。这应该给你2之间的最小差异

  • 这有用吗

    基于我提出的以下Sql提琴

    SELECT 
      bal.uid, 
      bal.userId, 
      bal.balance, 
      bal.time,
      trn.timestamp,
      trn.description,
      datediff(ms, bal.time, trn.timestamp)
    FROM 
      money_balances bal
      JOIN money_transaction trn on
        trn.userid = bal.userid and
        trn.uid =
        (
          select top 1 uid
          from money_transaction trn2
          where trn2.userid = trn.userid
          order by abs(datediff(ms, bal.time, trn2.timestamp))
        )
    WHERE 
      bal.time IS NOT NULL
    ORDER BY 
      bal.time DESC
    
    我不能保证它的性能,因为我对你的数据一无所知,但我相信它是有效的

    我简化了我的答案——我相信你需要的是

    SELECT 
      bal.uid as baluid,   
      (
          select top 1 uid 
          from money_transaction trn2
          where trn2.userid = bal.userid
          order by abs(datediff(ms, bal.time, trn2.timestamp))
      ) as tranuid
    FROM 
      money_balances bal
    
    从中你可以得到你需要的所有数据集。 例如:

    with matched_credits as
    (
    SELECT 
      bal.uid as baluid,   
      (
          select top 1 uid 
          from money_transaction trn2
          where trn2.userid = bal.userid
          order by abs(datediff(ms, bal.time, trn2.timestamp))
      ) as tranuid
    FROM 
      money_balances bal 
    )
    select 
      *
    from 
      matched_credits mc
      join money_balances mb on
        mb.uid = mc.baluid
      join money_transaction trn on
        trn.uid = mc.tranuid
    
    尝试:


    你能根据第一条建议帮我吗。。?这有可能吗?如果您提供带有内部联接的查询,则会更有帮助。我们将必须查看您的表和一些示例数据,但解决方案肯定可用-您所要求的并非不可能。我已使用表结构更新了我的问题。您能签出吗?我已在此处签出,但是,1.我遇到了此错误“datediff函数导致溢出。分隔两个日期/时间实例的DatePart数量太多。尝试将datediff与不太精确的datepart一起使用。“2.这里似乎还考虑了datediff的'ms'部分。它可能是小时、分钟等(唯一的条件是时间戳接近时间)1.我想那是因为我不得不猜测你的数据类型。请看下面Mark的帖子-将其转换为浮动可能是最好的。另外,请参考上面两个表中的预期结果集。
    with matched_credits as
    (
    SELECT 
      bal.uid as baluid,   
      (
          select top 1 uid 
          from money_transaction trn2
          where trn2.userid = bal.userid
          order by abs(datediff(ms, bal.time, trn2.timestamp))
      ) as tranuid
    FROM 
      money_balances bal 
    )
    select 
      *
    from 
      matched_credits mc
      join money_balances mb on
        mb.uid = mc.baluid
      join money_transaction trn on
        trn.uid = mc.tranuid
    
    SELECT dbo.bal.uid,
           dbo.bal.userId,
           dbo.bal.balance,
           dbo.bal.time,
      (SELECT TOP 1 transactionBal
       FROM dbo.transaction
       ORDER BY abs(datediff(ms, dbo.bal.time, TIMESTAMP))) AS newBal
    FROM dbo.bal
    WHERE dbo.bal.time IS NOT NULL
    ORDER BY dbo.bal.time DESC