MySQL中使用IF或EXISTS的WHERE

时间:2014-05-21 19:33:55

标签: mysql if-statement join where

我对tableC中不存在的id的以下查询有问题。尽管有LEFT JOIN,但如果tableC中没有id,则tableA和tableB中的id不在结果中。这是因为这些id不存在tableC.name。我想,MySQL会忽略最后一部分,考虑到该条款是真的......但是没有。

SELECT
    tableA.id, tableA.name
FROM
    tableA
    LEFT JOIN tableB ON tableA.id = tableB.id
    LEFT JOIN tableC ON tableA.id = tableC.id
WHERE
    tableA.latin = 'whatever'
    AND RIGHT(tableC.name,2) != 'y'

我想在WHERE子句的第二部分有一个使用IF,CASE或EXISTS的解决方案,但我没有得到我想要的结果以下三次尝试(我只显示最后一行):< / p>

WHERE
    tableA.latin = 'whatever'
    AND IF(tableC.name <> 0, RIGHT(tableC.name,2) != 'y', ' ');

这也不会产生错误,但不会产生预期的结果:

WHERE
    tableA.latin = 'whatever'
    AND IF(tableC.name = true, RIGHT(tableC.name,2)!= 'y', ' ');

使用EXISTS尝试以下操作会让我在MySQL Wordbench编辑器中出错:

WHERE
    tableA.latin = 'whatever'
    AND if(EXISTS tableC.name, RIGHT(tableC.name,2) != 'y', ' ');

3 个答案:

答案 0 :(得分:1)

每当您从where子句中的左连接表引用列(在您的情况下为tableC.name)时,您强制连接的行为就像它是内连接一样。相反,将测试移动到连接条件。

SELECT tableA.id, tableA.name 
    FROM tableA
        LEFT JOIN tableB 
            ON tableA.id = tableB.id
        LEFT JOIN tableC 
            ON tableA.id = tableC.id
                AND RIGHT(tableC.name,2) != 'y'
    WHERE tableA.latin =  'whatever' 

答案 1 :(得分:0)

有一个更简单的解决方案。您的where条件正在将外连接转换为内连接。只需将条件移入on子句:

SELECT tableA.id, tableA.name FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.id
LEFT JOIN tableC ON tableA.id = tableC.id AND RIGHT(tableC.name, 2) <> 'y'
WHERE tableA.latin =  'whatever';

当然,表达式RIGHT(tableC.name,2) != 'y'几乎总是应该是真的,因为你正在寻找两个字符并与之比较。也许你的意思是:

SELECT tableA.id, tableA.name FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.id
LEFT JOIN tableC ON tableA.id = tableC.id AND tableC.name not like '%y'
WHERE tableA.latin =  'whatever';

答案 2 :(得分:0)

这个怎么样(未经测试,但我认为它应该有效):

SELECT tableA.id, tableA.name FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.id
LEFT JOIN tableC ON (tableA.id = tableC.id AND RIGHT(tableC.name,2) != 'y') 
WHERE tableA.latin =  'whatever' 

它使表c只包含你想要的但不干扰左外连接。