Mysql连接表结果为一行

时间:2014-12-06 12:34:21

标签: mysql join group-concat

我有两张桌子

PRJ

id | ptitle
1  | prj111
2  | prj222

prjflow

id | pid | paction | pactiontxt
 1 |  1  |    1    |     man1
 2 |  1  |    1    |     man2
 3 |  1  |    2    |     woman1
 4 |  1  |    1    |     man3

我想要这个输出:

输出

ptitle | men       | women
prj111 | man1,men3 | woman1

我写这个查询:

SELECT prj.ptitle
     , GROUP_CONCAT(pflow1.pactiontxt) men
     , GROUP_CONCAT(pflow2.pactiontxt) women 
  FROM prj 
  JOIN prjflow pflow1 
    ON prj.id = pflow1.pid 
   AND pflow1.paction = 1
  JOIN prjflow pflow2 
    ON prj.id = pflow2.pid 
   AND pflow2.paction = 2;

但输出是:

ptitle | men       | women
prj111 | man1,men3 | woman1,woman1

我的查询当男女行数相等,工作正常 但 我想在任何情况下都有效。

非常感谢 并原谅我写英文不好

2 个答案:

答案 0 :(得分:3)

只需使用条件聚合:

SELECT prj.ptitle,
       GROUP_CONCAT(CASE WHEN prjflow.paction = 1 THEN prjflow.pactiontext END ORDER BY prjflow.id) as men,
       GROUP_CONCAT(CASE WHEN prjflow.paction = 2 THEN prjflow.pactiontext END ORDER BY prjflow.id) as women
FROM prj JOIN
     prjflow 
     ON prj.id = prjflow.pid
GROUP BY prj.ptitle;

这也将解决您的查询的两个潜在问题。首先是表现。如果某些标题有大量的男性和女性,则查询必须处理笛卡尔积。第二个是语义。如果某些头衔有男性而有女性或女性没有男性,那么这两个联合会过滤掉它们。

Here是一个证明它的SQL小提琴。

请注意,建议的输出似乎与输入数据不一致。这会产生输出:

ptitle | men            | women
prj111 | man1,man2,men3 | woman1  

我认为没有合理的方法从列表中排除man2,所以我认为这是一个错字。

答案 1 :(得分:0)

快速修复'将在distinct聚合中使用group_concat

SELECT 
  prj.ptitle, 
  group_concat(distinct pflow1.pactiontxt) AS men, 
  group_concat(distinct pflow2.pactiontxt) AS women 
FROM prj 
JOIN prjflow AS pflow1 ON (prj.id = pflow1.pid AND pflow1.paction = 1) 
JOIN prjflow AS pflow2 ON (prj.id = pflow2.pid AND pflow2.paction = 2)
GROUP BY
  prj.ptitle -- Officially you'll need this as well, although MySQL is quite forgiving.

但是查询仍然使用两个连接,如果特定项目中没有男性或没有女性,则甚至会失败。

因此,要解决此问题,您可以使用子查询编写查询。这样,您就不会需要加入distinctgroup by,当项目根本没有男性或没有女性时,查询也会起作用。

SELECT 
  prj.ptitle, 
  ( SELECT group_concat(pflow1.pactiontxt) FROM prjflo pflow1 
    WHERE prj.id = pflow1.pid AND pflow1.paction = 1) AS men,
  ( SELECT group_concat(pflow2.pactiontxt) FROM prjflo pflow2 
    WHERE prj.id = pflow2.pid AND pflow2.paction = 2) AS women
FROM prj