带OR条件的sql多连接

时间:2012-08-21 09:07:40

标签: mysql sql

我有三张桌子AA,BB和CC。 BB和CC具有一对一映射到表AA(具有外键列:两个表中的aa_id)。提供了一个条件,即只有BB或CC可以引用一行表AA。

我想从AA中选择最新 1000行,或者加入BB或CC。 我可以单独查询以选择500行分别与BB和CC连接并生成1000.但这并不能保证我从AA表中获取最新的1000行。

所以,我想出了以下查询,通过同时加入BB和CC从AA中选择记录。但是由于我的限制(只有BB或CC可以引用一行表AA),我从下面的查询得到0行。

SELECT  * FROM AA 
       INNER JOIN BB  ON (
            AA.id = BB.aa_id
            AND SOME_CONDITION
        ) 
        INNER JOIN CC  ON (
            AA.id = CC.aa_id
            AND SOME_CONDITION
        )
ORDER BY
AA.id DESC limit 1000;

你能告诉我怎么做吗?有没有什么方法可以让我这两个JOIN条件?

5 个答案:

答案 0 :(得分:3)

只需将INNER JOIN更改为LEFT OUTER JOIN,您就可以了。您可能需要阅读this article on codinghorror.com以获取不同连接类型的说明。

您的结果应如下所示:

SELECT * FROM AA 
  LEFT OUTER JOIN BB  ON (
    AA.id = BB.aa_id
    AND /* SOME_CONDITION */
  ) 
  LEFT OUTER JOIN CC  ON (
    AA.id = CC.aa_id
    AND /* SOME_CONDITION */
  )
ORDER BY AA.id DESC
LIMIT 1000;

答案 1 :(得分:1)

由于BB中的每一行CCAA只有一个匹配,因此您应将INNER JOIN替换为LEFT OUTER JOIN。< / p>

所以查询应该是:

SELECT * FROM AA 
    LEFT OUTER JOIN BB ON (
        AA.id = BB.aa_id
        AND SOME_CONDITION
    ) 
    LEFT OUTER JOIN CC ON (
        AA.id = CC.aa_id
        AND SOME_CONDITION
    )
ORDER BY
AA.id DESC limit 1000;

答案 2 :(得分:1)

如果您想要AA中的所有记录,其中BB或CC中的相应记录存在,您甚至不必加入(假设您不需要BB和CC中的值) 。请改用EXISTS

SELECT *  FROM AA
    WHERE
    (
        EXISTS (
            SELECT 1 FROM BB WHERE AA.id = BB.aa_id
                /* AND SOME_CONDITION */
        ) OR EXISTS (
            SELECT 1 FROM CC WHERE AA.id = CC.aa_id
                /* AND SOME_CONDITION */)
    )
    ORDER BY AA.id DESC limit 1000;

对我来说看起来更干净(而且它可能会更快一些,因为处理的数据更少,但我还没有对其进行测试)!

答案 3 :(得分:0)

编辑:你说'最后1000行的AA',所以要注意在选择中指定AA。*,否则你将获得由AA组成的1000行,然后是所有字段BB和CC的所有字段(两个集合中的一个也将为NULL)。

这将获得与BB或CC(或两者)匹配的最后1000行AA:

SELECT  AA.* FROM AA
   LEFT JOIN BB  ON (
        AA.id = BB.aa_id
        AND SOME_CONDITION
    ) 
    LEFT JOIN CC  ON (
        AA.id = CC.aa_id
        AND SOME_CONDITION
    )
    WHERE (BB.aa_id IS NOT NULL OR CC.aa_id IS NOT NULL)
ORDER BY AA.id DESC LIMIT 1000;

答案 4 :(得分:0)

@oezi是绝对正确的。您的查询中只需要进行少量更改,只需删除INNER JOIN即可。使用LEFT OUTER JOIN AND条件作为@oeze提及。