3

我有三张桌子 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;

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

4

5 回答 5

3

只需将您INNER JOIN的 s 更改为LEFT OUTER JOINs 即可。您可能想阅读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;
于 2012-08-21T09:10:08.547 回答
1

BB由于 中或CC中的每一行只有一个匹配项AA,因此您应该将 your 替换INNER JOINLEFT OUTER JOIN.

所以查询应该是:

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;
于 2012-08-21T09:10:55.253 回答
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;

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

于 2012-08-21T09:27:30.193 回答
0

编辑:您说“AA 的最后 1000 行”,因此请注意在选择中指定 AA.*,否则您将获得由 AA 组成的 1000 行,然后是 BB 的所有字段和 CC 的所有字段(其中一个这两组也将被清空)。

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

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;
于 2012-08-21T09:24:07.567 回答
0

@oezi 是绝对正确的。您的查询几乎不需要更改,只需删除INNER JOIN. LEFT OUTER JOINAND@oeze 提到的条件一起使用。

于 2012-08-21T09:42:51.560 回答