新手求助:用SQL统计初始ID的关联跟进ID数量及生成关联列表
解决方法:递归CTE处理跟进ID链
这是典型的层级/链式数据遍历场景,用递归CTE(Common Table Expressions)就能高效解决,不需要手动循环。下面分步骤说明:
前提假设
假设你的表名为follow_records,字段为id和follow-up id(注意字段名含空格,SQL中需要用反引号/双引号包裹)。
核心思路
- 定位初始ID:找出所有没有被当作
follow-up id的ID——这些就是链条的起点。 - 递归遍历链条:从每个初始ID出发,顺着
follow-up id往下遍历,记录完整的ID链和链长度。 - 聚合结果:按初始ID分组,提取完整的链信息和统计数。
示例SQL代码(PostgreSQL版本)
WITH RECURSIVE follow_chain AS ( -- 第一步:筛选初始ID,初始化链信息 SELECT id AS initial_id, id AS current_id, ARRAY[id] AS linked_ids, 1 AS count FROM follow_records WHERE id NOT IN ( SELECT DISTINCT "follow-up id" FROM follow_records WHERE "follow-up id" IS NOT NULL ) UNION ALL -- 第二步:递归遍历后续ID,更新链信息 SELECT fc.initial_id, fr.id AS current_id, fc.linked_ids || fr.id AS linked_ids, fc.count + 1 AS count FROM follow_chain fc JOIN follow_records fr ON fc.current_id = fr."follow-up id" ) -- 第三步:聚合得到最终结果 SELECT initial_id, MAX(count) AS count, ARRAY_TO_STRING(MAX(linked_ids), ', ') AS linked_id_list FROM follow_chain GROUP BY initial_id ORDER BY initial_id;
示例SQL代码(MySQL 8.0+版本)
MySQL不支持数组,直接用字符串拼接:
WITH RECURSIVE follow_chain AS ( SELECT id AS initial_id, id AS current_id, CAST(id AS CHAR(200)) AS linked_ids, 1 AS count FROM follow_records WHERE id NOT IN ( SELECT DISTINCT `follow-up id` FROM follow_records WHERE `follow-up id` IS NOT NULL ) UNION ALL SELECT fc.initial_id, fr.id AS current_id, CONCAT(fc.linked_ids, ', ', fr.id) AS linked_ids, fc.count + 1 AS count FROM follow_chain fc JOIN follow_records fr ON fc.current_id = fr.`follow-up id` ) SELECT initial_id, MAX(count) AS count, MAX(linked_ids) AS linked_id_list FROM follow_chain GROUP BY initial_id ORDER BY initial_id;
代码解释
- 锚点查询:筛选初始ID,给每个初始ID初始化一个包含自身的链,计数为1。
- 递归查询:把上一轮的当前ID作为
follow-up id关联表,找到下一个ID,把它追加到链中,计数加1,直到没有后续ID(join不到数据)停止递归。 - 聚合查询:每个初始ID会生成多条递归记录(对应链的每一段),取最大计数和对应的完整链,就是最终需要的结果。
注意事项
- 如果你的数据库版本过低(比如MySQL 5.x),不支持递归CTE,需要用存储过程实现循环,但递归CTE是更简洁高效的方案。
- 字段名含空格时,必须用反引号(MySQL)或双引号(PostgreSQL)包裹,否则会报错。
内容的提问来源于stack exchange,提问作者ballerinacoder
相关产品推荐
相关产品推荐

