MySQL:将多个不同的表合并为一个

时间:2014-04-09 19:27:31

标签: mysql sql

我有多个表,比如说A,B和C,其中B和C有一个A的外键。

我想编写一个返回结果集的查询,其中结果集的列是A,B和C组合的列,即

A.id A.name B.id B.name C.id C.name
-----------------------------------
1    Thing  2    Bee    NULL NULL
1    Thing  NULL NULL   1    Cow

即,基本上是B和C上单个LEFT OUTER JOIN的结果的组合,但是组合成单个结果集。我很好,有多个NULL列。

编辑:结果集将始终具有A的条目,但只有B或C中的一个。

这可能吗?或者有更好的方法来加入这些信息吗?

1 个答案:

答案 0 :(得分:1)

由于您从不希望单行同时包含BC,因此您可以UNION将两个单独的连接查询放在一起,将NULL文字替换为相反的表格让列对齐。 UNION的每个部分都提供A->BA->C之间的关系,但必须为对方表的所有列返回NULL。提供NULL个文字,以便从另一个表中留空每列。

最后要对它们进行排序,您可以有条件地检查B列是否为NOT NULL,以强制B行在C行之前排序首先按A.id排序。

(
  SELECT 
    A.id AS a_id,
    A.name AS a_name,
    B.id AS b_id,
    B.name AS b_name,
    /* Substitute NULLs... for the other table C, for *all columns* */
    NULL AS c_id,
    NULL AS c_name,
    NULL AS other_c
    /* etc, other cols from C */
  FROM A
    LEFT JOIN B ON A.id = B.a_id
/* UNION, rather than UNION ALL  in case both tables have NULLs */
) UNION (
  SELECT
    A.id AS a_id,
    A.name AS a_name,
    /* This time substitute NULLs for B, again *all columns* */
    NULL AS b_id,
    NULL AS b_name,
    C.id AS c_id,
    C.name AS c_name
    C.other_c
  FROM A
    LEFT JOIN C ON A.id = C.a_id
)
ORDER BY 
  a_id,
  /* sort the non-null B ahead... */
  CASE WHEN b_id IS NOT NULL THEN 0 ELSE 1 END