LEFT JOIN
OUTER APPLY
に置き換える必要があります 以下の状況で。
<強い>1. TOP n
に基づいて 2 つのテーブルを結合する場合 結果
Id
を選択する必要があるかどうかを検討してください と 名前
マスター
から 各 Id
の最後の 2 つの日付 詳細code>から
SELECT M.ID,M.NAME,D.PERIOD,D.QTYFROM MASTER MLEFT JOIN(SELECT TOP 2 ID, PERIOD,QTY FROM DETAILS D ORDER BY CAST(PERIOD AS DATE)DESC)DON M. ID=D.ID
プレ>次の結果を形成します
x------x---------x--------------x-------x| ID |名前 |期間 |数量 |x------x---------x--------------x-------x| 1 |あ | 2014-01-13 | 10 || 1 |あ | 2014-01-12 | 20 || 2 |ビ |ヌル |ヌル || 3 |シー |ヌル | NULL |x-----x---------x--------------x-------x
プレ>これは間違った結果をもたらします。つまり、
Details
から最新の 2 つの日付データのみをもたらします。Id
に関係なくテーブルId
で結合しても .したがって、適切な解決策はOUTER APPLY
を使用することです .SELECT M.ID,M.NAME,D.PERIOD,D.QTYFROM MASTER MOUTER APPLY( SELECT TOP 2 ID, PERIOD,QTY FROM DETAILS D WHERE M.ID=D.ID ORDER BY CAST(PERIOD AS DATE)DESC)D
プレ>これが作業です:
LEFT JOIN
、TOP 2
日付はMASTER
に結合されます 派生テーブルD
内でクエリを実行した後のみ .OUTER APPLY
で 、結合WHERE M.ID=D.ID
を使用しますOUTER APPLY
内 、各ID
マスター
でTOP 2
に参加します 次の結果をもたらす日付。x------x---------x--------------x-------x| ID |名前 |期間 |数量 |x------x---------x--------------x-------x| 1 |あ | 2014-01-13 | 10 || 1 |あ | 2014-01-12 | 20 || 2 |ビ | 2014-01-08 | 40 || 2 |ビ | 2014-01-06 | 30 || 3 |シー |ヌル | NULL |x-----x---------x--------------x-------x
プレ><強い>2.
LEFT JOIN
が必要な場合関数
を使用した機能 .
外部適用
LEFT JOIN
の代わりに使用できますMaster
から結果を取得する必要がある場合 テーブルと関数
.SELECT M.ID,M.NAME,C.PERIOD,C.QTYFROM MASTER MOUTER APPLY dbo.FnGetQty(M.ID) C
プレ>関数はここにあります。
CREATE FUNCTION FnGetQty ( @Id INT )RETURNS TABLE ASRETURN ( SELECT ID,PERIOD,QTY FROM DETAILS WHERE [email protected] )コード> プレ>
次の結果を生成しました
x------x---------x--------------x-------x| ID |名前 |期間 |数量 |x------x---------x--------------x-------x| 1 |あ | 2014-01-13 | 10 || 1 |あ | 2014-01-11 | 15 || 1 |あ | 2014-01-12 | 20 || 2 |ビ | 2014-01-06 | 30 || 2 |ビ | 2014-01-08 | 40 || 3 |シー |ヌル | NULL |x-----x---------x--------------x-------x
プレ><強い>3.
NULL
を保持 ピボット解除時の値以下のテーブルがあると考えてください
x------x-------------x--------------x| ID | FROMDATE | TODATE |x-----x-------------x--------------x| 1 | 2014-01-11 | 2014-01-13 | | | 1 | 2014-02-23 | 2014-02-27 | | | 2 | 2014-05-06 | 2014-05-30 | | | 3 |ヌル |ヌル | x-----x-------------x--------------x
プレ>
UNPIVOT
を使用する場合FROMDATE
を持ってくる ANDTODATE
1 列にすると、NULL
が削除されます デフォルトの値です。SELECT ID,DATESFROM MYTABLEUNPIVOT (列の日付 (FROMDATE,TODATE)) P
プレ>以下の結果が生成されます。
<前>Id
の記録が抜けていることに注意してください 番号3
x------x-------------x | ID |日付 | x-----x-------------x | 1 | 2014-01-11 | | | 1 | 2014-01-13 | | | 1 | 2014-02-23 | | | 1 | 2014-02-27 | | | 2 | 2014-05-06 | | | 2 | 2014-05-30 | x-----x-------------x
プレ>そのような場合、
APPLY
使用できます (CROSS APPLY
のいずれか) またはOUTER APPLY
、交換可能です)。SELECT DISTINCT ID,DATESFROM MYTABLE OUTER APPLY(VALUES (FROMDATE),(TODATE))COLUMNNAMES(DATES)
プレ>次の結果を形成し、
<前>Id
を保持します その値は3
ですx------x-------------x | ID |日付 | x-----x-------------x | 1 | 2014-01-11 | | | 1 | 2014-01-13 | | | 1 | 2014-02-23 | | | 1 | 2014-02-27 | | | 2 | 2014-05-06 | | | 2 | 2014-05-30 | | | 3 |ヌル | x-----x-------------x
プレ>