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 example@sqldat.com )コード> プレ>次の結果を生成しました
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を持ってくる ANDTODATE1 列にすると、NULLが削除されます デフォルトの値です。SELECT ID,DATESFROM MYTABLEUNPIVOT (列の日付 (FROMDATE,TODATE)) Pプレ>以下の結果が生成されます。
<前>Idの記録が抜けていることに注意してください 番号3x------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プレ>