【问题标题】:SQL Query to Join Two Tables Based On Closest Timestamp基于最近时间戳连接两个表的 SQL 查询
【发布时间】:2013-03-31 15:30:15
【问题描述】:

我需要从 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

这是我的表结构,

dbo.transaction
---------------

| uid| userId   | description| timestamp               | credit | transactionBal
-------------------------------------------------------------------------
| 1  | 101      | buy credit1| 2012-01-25 03:23:31.624 | 100    | 500
| 2  | 102      | buy credit5| 2012-01-18 03:13:12.657 | 500    | 700
| 3  | 103      | buy credit3| 2012-01-15 02:16:34.667 | 300    | 300
| 4  | 101      | buy credit2| 2012-01-13 05:34:45.637 | 200    | 300
| 5  | 101      | buy credit1| 2012-01-12 07:45:21.457 | 100    | 100
| 6  | 102      | buy credit2| 2012-01-01 08:18:34.677 | 200    | 200

dbo.bal
-------

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

结果应该是这样的,

| 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

请帮助我..任何帮助都必须感谢...谢谢

【问题讨论】:

  • 还提到了上述两个表中所需的结果集。

标签: sql sql-server sql-server-2008 join timestamp


【解决方案1】:

如果您发布表结构会很有帮助,但是...

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

  2. 内部查询中的ORDER BY 子句可能是ABS(TIMESTAMP - DB0.BAL.TIME)。这应该会给你两者之间的最小差异。

这有帮助吗?

基于以下 Sql Fiddle http://sqlfiddle.com/#!3/7a900/15 我想出了...

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 函数导致溢出。分隔两个日期/时间实例的 dateparts 的数量太大。尝试使用带有 less 的 datediff精确的日期部分。” 2. 此外,您似乎在这里考虑 datediff 的 'ms' 部分。它可能是 hours 、 minits 等(唯一条件是接近时间的时间戳)
  • 1.我认为那是因为我不得不猜测您的数据类型。看看下面 Mark 的帖子 - 转换为浮动可能是最好的。
【解决方案2】:

试试:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-26
    • 1970-01-01
    • 2021-07-08
    • 1970-01-01
    相关资源
    最近更新 更多