MySQL将多行查询连接到一列

时间:2014-04-12 19:25:41

标签: php mysql sql

表格结构

client_commands (" main"表):
id | completed

command_countries
id | command_id | country_code

command_os
id | command_id |OS

command_id on引用client_commands上的id列。

问题

我可以使用基于国家/地区和操作系统的过滤器添加客户端命令。要尝试规范化我的数据库结构,请为每个新命令添加:

  • 向client_commands
  • 添加新行
  • 对于每个国家/地区,我向command_countries添加一个新行,每个行引用client_command.id
  • 对于每个操作系统,我向command_os添加一个新行,每个行引用client_command.id

对于我网站上的其中一个页面,我需要显示所有client_commands(其中completed = 0)以及该命令的所有国家/地区和操作系统。我想要的输出是这样的:

id | countries | OS
1  | GB, US, FR| 2, 3
2  | ES, HU    | 1, 3

我不确定该怎么做。我使用的当前查询返回多行:

SELECT a.id, b.country_code, c.OS
FROM client_commands a
LEFT JOIN command_countries b on b.command_id = a.id
LEFT JOIN command_os c on c.command_id = a.id
WHERE a.completed = 0

Query results

任何帮助?

谢谢!

编辑:我忘了提及(如果你无法从上面推断) - 每个命令可以有不同数量的操作系统和国家。

-

另外:我知道我可以通过拉动所有命令,然后循环并为每个结果运行2个额外查询来完成此操作。但是,如果可以的话,我希望通过一个查询尽可能高效地完成它。

1 个答案:

答案 0 :(得分:3)

您可以使用GROUP_CONCAT

在一个查询中执行此操作
SELECT a.id, 
GROUP_CONCAT(DISTINCT b.country_code SEPARATOR ' ,') `countries`, 
GROUP_CONCAT(DISTINCT  c.OS SEPARATOR ' ,') `os`, 
FROM client_commands a
LEFT JOIN command_countries b on b.command_id = a.id
LEFT JOIN command_os c on c.command_id = a.id
WHERE a.completed = 0
GROUP BY a.id

如果您想要连续排序的结果,可以在GROUP_CONCAT中使用ORDER BY

GROUP_CONCAT(b.country_code ORDER BY b.command_id DESC SEPARATOR ' ,') `countries`

但请注意,默认情况下,concat设置限制为1024个字符,但这可以增加b,manual中提供的步骤