我有3张桌子,CAL,SOURCE,HISTORY。
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个表时,incodition nulls被过滤掉。请帮我纠正查询。
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
答案 0 :(得分:1)
您需要更好地了解LEFT JOIN的工作原理(外部连接一般 - 左/右和全[外]连接)
LEFT JOIN始终分两步执行:
SELECT ....
FROM table1
LEFT JOIN table1 ON join_conditions
WHERE where_conditions
步骤1 - 首先执行LEFT JOIN(使用ON子句中指定的条件连接两个表)
步骤2-WHERE条件应用于步骤1中的连接所产生的结果集
LEFT JOIN的工作原理 - 快速提醒:LEFT JOIN始终返回左表中的所有行,即使右表中没有匹配的行也是如此。如果没有匹配(ON条件的计算结果为false),则LEFT JOIN为右表返回NULL
RIGHT JOIN以相同的方式工作,但它返回RIGHT表中的所有行,而不是左边的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
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
上面的查询给出了以下结果(注意严格方面最后3行中的NULL):
| 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 请参阅此演示:http://sqlfiddle.com/#!9/e2ed0/3
如果您还要获取具有NULL值的记录,则需要将此条件更改为:
WHERE ( H.STATUS='COMPLETED' OR H.STATUS IS NULL )
您也可以从WHERE子句中删除该条件,并将其添加到LEFT JOIN的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