php - MySQL 将多行查询连接到一列中

标签 php mysql sql

表结构

client_commands(“主”表):
id |已完成

command_countries:
id |命令 ID |国家/地区代码

command_os:
id | command_id |操作系统

command_id on 引用 client_commands 上的 id 列。

问题

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

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

对于我网站上的其中一个页面,我需要显示所有 client_commands(其中已完成 = 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 个附加查询来做到这一点。但如果可以的话,我希望通过一次查询尽可能高效地完成此操作。

最佳答案

您可以使用 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`

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

关于php - MySQL 将多行查询连接到一列中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23035065/

相关文章:

php - 数据库输出未显示。获取 else 语句

php - 如何修复 php.DEBUG : fsockopen() :Connection refused?

php - PDO 与 bindValue 绑定(bind)不起作用

MySQL - 如何在此全文搜索中插入一个附加的 where 子句

mysql - RMySQL dbWriteTable 与 field.types

mysql - 选择其他行中具有条件的行

php - AJAX 加载整个页面而不是页面的一部分以从数据库加载数据

mysql - 使用 MySQL Workbench 访问 Lightsail 实例的数据库

mysql - 使用mysql从多个表动态行到列

php - 使用数组更新 SQL 查询