4

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

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

4

2 回答 2

4

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

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

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

这有帮助吗?

基于以下 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
于 2013-04-09T09:38:28.457 回答
1

尝试:

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
于 2013-04-09T11:35:31.960 回答