MySQL 查询结果由列转成行数据
行内字段拼接组合可以用到 CONCAT()
,如果需要指定分隔符可以使用 CONCAT_WS(',', xx, xx..)
,但如何将多行数据提取到单行结果中呢?
明确需求是,递归查询所属下级的id,最终用表中的 id 拼接成字串。这当然可以放在 php 代码里使用 implode 函数去实现,但这次需要通过 sql 做一个临时的查询。
因为所属下级最大层级为 3 级,所以可以通过 sql 的 union 将结果组合在一起。假设当前用户 id 为 9527,基本的 sql 如下:
SELECT id FROM users WHERE parent_id IN
(SELECT id FROM users WHERE parent_id IN
(SELECT id FROM users WHERE parent_id = 9527))
UNION
SELECT id FROM users WHERE parent_id IN
(SELECT id FROM users WHERE parent_id = 9527)
UNION
(SELECT id FROM users WHERE parent_id = 9527)
UNION SELECT 9527
最后的 UNION SELECT 9527
是将当前的用户 id 也包含在内。
通过百度查询到一个聚合函数 GROUP_CONCAT()
,它可以实现组合拼接。使用方法如下:
group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator '分隔符'] )
去除可能存在的重复项:
SELECT GROUP_CONCAT(DISTINCT CONCAT_WS(',', res.id) SEPARATOR ',') AS id_str
FROM (xxx) AS res
与子查询组合起来使用:
SELECT GROUP_CONCAT(DISTINCT CONCAT_WS(',', res.id) SEPARATOR ',') AS id_str
FROM (
SELECT id FROM users WHERE parent_id IN
(SELECT id FROM users WHERE parent_id IN
(SELECT id FROM users WHERE parent_id = 9527))
UNION
SELECT id FROM users WHERE parent_id IN
(SELECT id FROM users WHERE parent_id = 9527)
UNION
(SELECT id FROM users WHERE parent_id = 9527)
UNION SELECT 9527
) AS res
作为聚合函数,经常会与 group by 之类的分组查询结合在一起,需要注意的是:
在有 group by 的查询语句中,select 指定的字段要么就包含在 group by 语句的后面,作为分组的依据,要么就包含在聚合函数中。