4

dbo.bal の時間に最も近いタイムスタンプを持つ dbo.transaction (すべてのユーザーのトランザクション - 各ユーザーの複数のトランザクション) からレコードを取得する必要があります (各ユーザーの現在の残高の詳細 - それぞれに 1 つのレコードのみ)ユーザー)

つまり、結果のレコードは、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 に答える