2016-05-16 89 views
0

提供了以下的結構和數據:SQL:加入兩個表的/結合,在多個條件

CREATE TABLE "CHANGES" ( 
    "ID" NUMBER(38), 
    "LAST_UPD_DATE" DATE DEFAULT SYSDATE 
); 

CREATE TABLE "EXPORT_LOG" (
    "ID" NUMBER(38), 
    "LAST_EXPORT" DATE DEFAULT SYSDATE 
); 

CHANGES包含:

---------------------------- 
| ID | LAST_UPD_DATE  | 
---------------------------- 
| 123 | 12-MAY-16 12.23.23 | 
| 124 | 12-MAY-16 12.24.23 | 
| 125 | 12-MAY-16 12.11.23 | 
---------------------------- 

EXPORT_LOG

---------------------------- 
| ID | LAST_EXPORT  | 
---------------------------- 
| 124 | 12-MAY-16 12.23.12 | 
| 125 | 12-MAY-16 12.12.24 | 
---------------------------- 

我需要獲取CHANGES中的記錄,這些記錄不存在於EXPORT_LOG或者,如果存在,則獲得比LAST_EXPORTLAST_UPD_DATE的記錄。 所以在上面的例子中,我應該得到123和124

我嘗試不同的連接,但我似乎無法得到我想要的結果: INNER JOIN用於十字路口,LEFT JOIN獲取所有第一表,但只有那些符合你設定條件的第二張表 - 這些都不是我想要的。那麼解決方案是什麼聯盟?

回答

3

試試這個:

SELECT t1.* 
FROM CHANGES AS t1 
LEFT JOIN EXPORT_LOG AS t2 ON t1.ID = t2.ID 
WHERE (t2.ID IS NULL) OR (t1.LAST_UPD_DATE > t2.LAST_EXPORT) 

這將返回沒有匹配CHANGES表中的所有記錄EXPORT_LOGCHANGES記錄有一個LAST_UPD_DATE晚於LAST_EXPORT

+0

謝謝,沒有工作。但是,你能解釋這是怎麼回事嗎?在'ON t1.ID = t2.ID'的結果之後是不是應用了where子句?因爲沒有'WHERE',沒有記錄't2.ID'爲'null' – mavili

+1

@mavili - 是的,有。這正是外連接(在這種情況下爲左連接)所做的 - 它創建了您正在討論的記錄,其中t1.id沒有相應的t2.id。 (請注意,這並不意味着「t2.id爲空」 - 不確定你的意思。) – mathguy

0

一種方法是直接轉換使用exists條件:

select c.* 
from changes c 
where not exists (select 1 from export_log el where c.id = el.id) or 
     not exists (select 1 from export_log el where c.id = el.id and el.last_export > c.last_upd_date); 

這可以簡化爲:

select c.* 
from changes c 
where not exists (select 1 from export_log el where c.id = el.id and el.last_export > c.last_upd_date); 
-1

請使用以下提到的代碼,並提供我的意見。它應該按照您的要求工作。

SELECT CH.ID, CH.LAST_UPD_DATE 
 
FROM CHANGES CH, EXPORT_LOG EL 
 
WHERE CH.ID = EL.ID(+) 
 
AND ((EL.ID IS NULL) OR (CH.LAST_UPD_DATE > EL.LAST_EXPORT));

+1

Giorgios已經發布了這個解決方案,但有一點不同:他使用推薦的連接語法。在此查詢中沒有理由使用過時的Oracle專有語法來進行外部連接。這個缺點是出於兩個原因,特別是對於第一個。 – mathguy