2016-05-11 8 views
1

私はCAL、SOURCE、HISTORYという3つのテーブルを持っています。私が使用しOracle - 複数のテーブルの左外部結合が目的のヌル値を返さない

CAL TABLE CAL_DATE 01/05/16 02/05/16 03/05/16 04/05/16 05/05/16 06/05/16 07/05/16

SOURCE TABLE TABLE_ID GROUP 1210 Sales 1211 Reference 1230 Marketing 1245 Sales 1650 Reference 1784 Sales

HISTORY
RUN_DATE TABLE_ID STATUS 01/05/16 1210 COMPLETED 02/05/16 1210 COMPLETED 02/05/16 1211 COMPLETED 03/05/16 1211 COMPLETED 01/05/16 1230 COMPLETED 03/05/16 1230 COMPLETED

クエリ。

SELECT TO_CHAR(C.CAL_DATE,'mm/dd/yyyy') AS CAL_DATE,TO_CHAR(C.CAL_DATE,'day') AS WDAY,X.* FROM CAL C LEFT OUTER JOIN 
(
    SELECT S.GROUP,S.TABLE_ID,H.RUN_DATE,H.STATUS FROM TABLE S 
    LEFT JOIN HISTORY H 
    ON S.TABLE_ID=H.TABLE_ID 
    WHERE 1=1 
    AND STATUS='COMPLETED'  
) X 
ON TO_CHAR(C.CAL_DATE,'dd/mm/yyyy')=TO_CHAR(RUN_DATE,'dd/mm/yyyy') 
AND X.TABLE_ID IN (1210,1211,1230) 
WHERE TO_CHAR(C.CAL_DATE,'mm/dd/yyyy') <= TO_CHAR('03/05/2016','mm/dd/yyyy') 
ORDER BY SOURCE_TABLE_ID ASC 

期待される出力は以下に示されていますが、出力が異なります。 1つ以上のテーブルIDを渡すと、NULLがフィルタリングされます。クエリを修正するのを手伝ってください。

あなたはLEFTの作品を登録しようどのようにより良い理解を得るために必要

CAL_DATE TABLEID Status 01/05/16 1210 Completed 02/05/16 1210 Completed 03/05/16 null null 01/05/16 null null 02/05/16 1211 Completed 03/05/16 1211 Completed 01/05/16 1230 Completed 02/05/16 null null 03/05/16 1230 Completed

+1

この条件で 'SOURCE_TABLE_ID'カラムを参照するため、このクエリはコンパイルも実行もできません:' X.SOURCE_TABLE_ID IN(1210,1211,1230) '、' X'という名前のサブクエリにはそのようなカラムは含まれていません選択リストの中で: 'SELECT S.GROUP、S.TABLE_ID、H.RUN_DATE、H.STATUS FROM ... ' – krokodilko

+0

それは私の悪いです。列名はTABLE_IDのみです。私はSOURCE_TABLE_IDを間違って配置しました。 –

+0

実行可能なクエリは次のとおりです。 TODCHAR(C.CAL_DATE、 'mm/dd/yyyy')AS CAL_DATE、TO_CHAR(C.CAL_DATE、 '日')AS WDAY、X。* CAL C左外部継ぎ手 ( SELECT S.GROUP、S。表S S.TABLE_ID = H.TABLE_ID の履歴H をJOIN左からTABLE_ID、H.RUN_DATE、H.STATUS WHERE 1 = 1 AND STATUS = 'COMPLETED' )X ON TO_CHAR(C.CAL_DATE、」 TO_CHAR(C.CAL_DATE、 'mm/dd/yyyy') TO_CHAR(CAL_DATE、' dd/mm/yyyy ')= TO_CHAR(RUN_DATE、' dd/mm/yyyy ') AND X.TABLE_ID IN 1210,1211,1230 = TO_CHAR('03/05/2016 '、' mm/dd/yyyy ') ORDER BY TABLE_ID、CAL_DATE ASC –

答えて

1

(外側は一般的に参加する - 左/右と[外側]フル参加)

LEFT JOINは、常に行われます -
(2つのテーブルを結合するためにON句で指定された条件を使用して)最初に実行されるJOIN LEFT

SELECT .... 
FROM table1 
LEFT JOIN table1 ON join_conditions 
WHERE where_conditions 

ステップ1:二段階で ステップ2 - WHERE条件がステップに参加することによって発生したresulsetに適用される1

LEFTは、作品のJOIN方法 - 迅速なリマインダー:LEFTは、左の表からそこのためにも、これらの行を返します常にすべての行を結合します右の表には一致しません。一致がない場合(ON条件はFALSEと評価されます)、LEFT JOINは、右側の表に対してNULLを返します。
RIGHT JOINは同じ方法で動作しますが、LEFT JOINという左側の行ではなく、RIGHTテーブルからすべての行を返します。このクエリを持っている場合


はSO:

SELECT S.GROUP,S.TABLE_ID,H.RUN_DATE,H.STATUS 
FROM source_table S 
LEFT JOIN HISTORY H 
ON S.TABLE_ID=H.TABLE_ID 
WHERE H.STATUS='COMPLETED' 

データベースが最初にLEFT JOINを実行し、それは次のとおりです。

SELECT S.GROUP,S.TABLE_ID,H.RUN_DATE,H.STATUS 
FROM source_table S 
LEFT JOIN HISTORY H 
ON S.TABLE_ID=H.TABLE_ID 

上記のクエリは次のような結果(通知のNULLでを与えますリフト側の最後の3行):

| S.GROUP | S.TABLE_ID |     H.RUN_DATE | H.STATUS | 
|-----------|------------|----------------------------|-----------| 
|  Sales |  1210 | January, 05 2016 00:00:00 | COMPLETED | 
|  Sales |  1210 | February, 05 2016 00:00:00 | COMPLETED | 
| Reference |  1211 | February, 05 2016 00:00:00 | COMPLETED | 
| Reference |  1211 | March, 05 2016 00:00:00 | COMPLETED | 
| Marketing |  1230 | January, 05 2016 00:00:00 | COMPLETED | 
| Marketing |  1230 | March, 05 2016 00:00:00 | COMPLETED | 
|  Sales |  1245 |      (null) | (null) | 
| Reference |  1650 |      (null) | (null) | 
|  Sales |  1784 |      (null) | (null) | 

そしてデータベースは、上記の結果セットにWHERE条件を実行します

WHERE H.STATUS='COMPLETED' 

NULL='COMPLETED'がFALSEに評価されるので、クエリの最終結果である:

|  GROUP | TABLE_ID |     RUN_DATE | STATUS | 
|-----------|----------|----------------------------|-----------| 
|  Sales |  1210 | January, 05 2016 00:00:00 | COMPLETED | 
|  Sales |  1210 | February, 05 2016 00:00:00 | COMPLETED | 
| Reference |  1211 | February, 05 2016 00:00:00 | COMPLETED | 
| Reference |  1211 | March, 05 2016 00:00:00 | COMPLETED | 
| Marketing |  1230 | January, 05 2016 00:00:00 | COMPLETED | 
| Marketing |  1230 | March, 05 2016 00:00:00 | COMPLETED | 

である:全てNULLがありましたスキップしました。

WHERE (H.STATUS='COMPLETED' OR H.STATUS IS NULL) 

あなたはまた、WHERE句からTHS条件を削除することができます:http://sqlfiddle.com/#!9/e2ed0/3


あなたがNULL値でもレコードを取得したい場合は、あなたがこの条件を変更する必要があります。
このデモを参照してください。 、そしてそれは、JOINをLEFTのON条件に追加します。

SELECT S.GROUP,S.TABLE_ID,H.RUN_DATE,H.STATUS 
FROM source_table S 
LEFT JOIN HISTORY H 
ON (S.TABLE_ID=H.TABLE_ID AND H.STATUS='COMPLETED') 

は、このデモの最後のクエリを参照してください。http://sqlfiddle.com/#!9/e2ed0/3

+0

WHERE句の素晴らしい説明は、LEFTをINNER結合問題に変えます。さて、私は、OR ... IS NULLではなく、onにフィルタを移動することをかなり強く好みました。 –

関連する問題