2016-02-24 46 views
0

我需要從mysql數據庫中檢索行,如下所示:我有一個合同表,一個合同行項目表和另一個名爲udac的表。根據合同訂單項與udac之間的關係,我需要所有沒有訂單項記錄的合同。如果有更好的方式來陳述這個問題,讓我知道。選擇相關記錄不存在的行

表結構

----contract---------------------  ---contractlineitem----------- 
| id | customer_id | entry_date |  | id | contract_id | udac_id | 
---------------------------------  ------------------------------ 
| 1 | 1234  | 2010-01-01 |  | 1 | 1   | 5  | 
| 2 | 2345  | 2016-01-31 |  | 2 | 1   | 2  | 
---------------------------------  | 3 | 1   | 1  | 
             | 4 | 2   | 4  | 
             | 5 | 2   | 2  | 
             ------------------------------ 

---udac---------- 
| id | udaccode | 
----------------- 
| 1 | SWBL/R | 
| 2 | SWBL | 
| 3 | ABL/R | 
| 4 | ABL  | 
| 5 | XRS/F | 
----------------- 

鑑於上述數據,合同2會出現,但合同1不會,因爲它有指向在/ F或/ R結束udacs contractlineitems。

這是我到目前爲止,但它是不正確的。

SELECT c.* 
    FROM contract c 
    JOIN contractlineitem cli 
    ON c.id = cli.contract_id 
WHERE c.entry_timestamp > '2016-01-01 00:00:00' 
    AND NOT EXISTS (
      SELECT cli.id 
       FROM contractlineitem cli_i 
       JOIN udac u 
       ON cli_i.udac_id = u.id 
      WHERE u.udaccode LIKE '%/F' OR u.udaccode LIKE '%/R' 
       AND cli_i.contract_id = cli.contract_id); 
+0

表結構,示例數據,預期輸出... http://stackoverflow.com/help/how-to-ask –

+0

@TomH修改後的問題。那個更好嗎? – lmerry213

+0

你需要在你的'OR'邏輯中放置圓括號,否則'AND'邏輯不會產生變化。操作順序。 –

回答

0

湯姆評論說你的WHERE子句是錯的,可能是你正在追逐的問題。此外,如果優化程序找不到更好的方法來執行此操作,則使用相關子查詢可能會對性能造成問題。

這裏是更好的方式來做到這一點使用OUTER JOIN:

SELECT c.* 
    FROM contract c 
    JOIN contractlineitem cli 
    ON c.id = cli.contract_id 
    LEFT OUTER JOIN udac u 
    ON (u.id = cli.udac_id 
     AND (u.udaccode LIKE '%/F' OR u.udaccode LIKE '%/R')) 
WHERE c.entry_timestamp > '2016-01-01 00:00:00' 
    AND u.id IS NULL 

嘗試了這一點,看看它是否你想要做什麼。該查詢基本上做了你所說的:它嘗試加入udac,代碼以'/ F'或'/ R'結尾,但它只接受那些無法找到匹配的代碼(u.id IS NULL)。

如果同一行多次返回不正確,請在前面扔一個distinct

相關問題