行内字段拼接组合可以用到 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 语句的后面,作为分组的依据,要么就包含在聚合函数中。

参考:MySQL 教程之 concat 以及 group_concat 的用法