我有两张桌子
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
我的查询当男女行数相等,工作正常 但 我想在任何情况下都有效。
非常感谢 并原谅我写英文不好
答案 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.
但是查询仍然使用两个连接,如果特定项目中没有男性或没有女性,则甚至会失败。
因此,要解决此问题,您可以使用子查询编写查询。这样,您就不会需要加入distinct
或group 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