MySQL:将另一个表中的2行合并为一个结果行

时间:2017-01-13 02:42:38

标签: mysql sql pivot

这些是假表名,但在我的实际问题中,想象一个业务规则,声明每个父项都有1个或2个子项。这些孩子的数量为0或1.同一父母的两个孩子不能有相同的数字。

我希望访问children行中的字段,但希望将值放入数字前缀字段中。例如:

parenttochildrenassoc:

+-------------+-------------+
|    parent   |    child    |
+-------------+-------------+
|      1      |      1      |
|      1      |      2      |
|      2      |      3      |
|      3      |      4      |
+-------------+-------------+

小孩:

+-------------+-------------+------------+
|    child    |    number   |    name    |
+-------------+-------------+------------+
|      1      |      0      |   Chuck    |
|      2      |      1      |   Sally    |
|      3      |      0      |   Carly    |
|      4      |      1      |   Billy    |
+-------------+-------------+------------+

期望的结果:

+-------------+-------------+------------+
|   parent    |    child0   |   child1   |
+-------------+-------------+------------+
|      1      |    Chuck    |    Sally   |
|      2      |    Carly    |     NULL   |
|      3      |     NULL    |    Billy   |
+-------------+-------------+------------+

我能得到的最近的是:

SELECT A.parent, C0.name as child0, C1.name as child1
FROM parenttochildassoc A
    LEFT JOIN children C0 ON C0.child = A.child AND C0.number = 0
    LEFT JOIN children C1 ON C1.child = A.child AND C1.number = 1

产生这个:

+-------------+-------------+------------+
|   parent    |    child0   |   child1   |
+-------------+-------------+------------+
|      1      |    Chuck    |     NULL   |
|      1      |     NULL    |    Sally   |
|      2      |    Carly    |     NULL   |
|      3      |     NULL    |    Billy   |
+-------------+-------------+------------+

我怎样才能弄平这个?它似乎与此answer中描述的“枢轴”非常相似,(其中一个提议的答案与我的尝试相同)但parenttochildrenassoc多对一的事实似乎打破了它。< / p>

2 个答案:

答案 0 :(得分:1)

您实际上可以通过条件聚合和一个连接来执行此操作:

SELECT a.parent,
       MAX(CASE WHEN c.number = 0 THEN c.name END) as child0,
       MAX(CASE WHEN c.number = 1 THEN c.name END) as child1
FROM parenttochildassoc a LEFT JOIN
     children c
     ON C0.child = A.child
GROUP BY a.parent;

您可以随意将其扩展为您想要的任意数量的孩子。

如果您可以与一个字段中的所有孩子一起生活,那么请使用group_concat()

SELECT a.parent,
       GROUP_CONCAT(c.name ORDER BY c.number) as children
FROM parenttochildassoc a LEFT JOIN
     children c
     ON C0.child = A.child
GROUP BY a.parent;

答案 1 :(得分:0)

您可以在parent列上添加分组以折叠相似的父行:

SELECT A.parent,
       MAX(C0.name) AS child0,
       MAX(C1.name) AS child1
FROM parenttochildassoc A
LEFT JOIN children C0
    ON C0.child = A.child AND C0.number = 0
LEFT JOIN children C1
    ON C1.child = A.child AND C1.number = 1
GROUP BY A.parent

这应该起作用的原因是MAX()函数忽略NULL值。因此,当聚合parent = 1的两行时,结果集中只会显示非NULL值。