2

画像をクリックして、テーブル構造と問題を確認してください http://i.stack.imgur.com/odWKL.png

ここに画像の説明を入力

SELECT B.ENTITYID, 
       B.BALANCEDATE,
       B.BALANCE, 
       MIN(DATEDIFF(DAY,B.BALANCEDATE,C.STATUSDATE)) RECENT
FROM   BALANCES B JOIN STATUS C ON B.ENTITYID = C.ENTITYID
GROUP  BY B.ENTITYID, B.BALANCEDATE,B.BALANCE
HAVING B.ENTITYID =1

私は次のことを試しましたが、ネストされた選択が同様の属性へのアクセスに問題があるため、それ以上進むことはできません:

4

3 に答える 3

2

例として、SQL Server 2012 を RDBMS として使用します。これは、必要な最初のクエリです。
この回答では、他の RDBMS システムには当てはまらない可能性がある SQL CTE (Common Table Expression) を利用しました。
SQL FIDDLE DEMO
クエリの説明:
1. 最初に [Balances] テーブルと [Status] テーブルを結合し、BalanceDate > StatusDate を使用して結果を除外し、両方のテーブルからすべての列を返します。これは、後ですべてが必要になるためです。
2. ステップ .1 の出力を [Entity] テーブルと結合し、EntityName を使用して結果を除外します。3 つのテーブルのすべての列をそのままにしておきます。重複する EntityID は必要ありません。
3. CTE を使用して結合を保存します
4. CTE を使用して結合出力に適用されたランクを保存します
5. ランク番号を使用して結果をフィルター処理し、BalanceDate で並べ替えます


;with CTE_AfterJoin
as 
(
    select E.EntityID, E.EnityName, C.BalanceDate, C.Balance, C.StatusDate, C.status
    from Entity E
    left join (
            select B.EntityID, B.BalanceDate, B.Balance,S.StatusDate, S.[Status]
            from Balances B 
            left join  [Status] S
            on B.EntityID = S.EntityID and B.BalanceDate > S.StatusDate
            ) C
    on E.EntityID = C.EntityID
    where E.EnityName = 'ABCD'
),
CTE_afterRank
as 
(
    select EnityName, BalanceDate, Balance, 
           rank() over (partition by BalanceDate order by StatusDate desc) as Rn, Status 
    from CTE_AfterJoin
)
select EnityName, BalanceDate, Balance, Status
from CTE_afterRank
where Rn = 1
order by BalanceDate desc
于 2013-03-30T08:17:02.530 に答える
1

Also in SQLServer2005+ you can use option with APPLY() operator.

The APPLY operator allows you to join two table expressions. Right table expression is processed every time for each row from the left table expression.The final result-set contains all the selected columns from the left table expression followed by all the columns of right table expression. OUTER APLLY for those rows for which there are no corresponding matches in right table expression, it contains NULL values in columns of right table expression.

SELECT e.EntityName, b.BalanceDate AS Date, b.Balance, o.Status
FROM Entity e JOIN Balances b ON e.EntityID = b.EntityID
              OUTER APPLY (
                           SELECT TOP 1 s.Status AS Status                           
                           FROM Status s
                           WHERE b.EntityID = s.EntityID 
                             AND s.StatusDate < b.BalanceDate
                           ORDER BY s.StatusDate DESC
                           ) o
WHERE e.EntityName = 'ABCD' 

For improving performance(force INDEX SEEK operation) use this indexes with INCLUDE clause.The INCLUDE clause adds the data at the lowest/leaf level, rather than in the index tree. This makes the index smaller because it's not part of the tree

CREATE INDEX x ON Status(StatusDate) INCLUDE(EntityID, Status)
CREATE INDEX x ON Entity(EntityName) INCLUDE(EntityID)
CREATE INDEX x ON Balances(EntityID, BalanceDate, Balance)

Demo on SQLFiddle

enter image description here

于 2013-03-30T09:32:48.633 に答える