2016-02-24 14 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

相关问题