You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写SQL查询统计单表中拥有相同子记录集的父记录数量

解决思路与SQL实现

核心思路

要统计每个父记录对应的相同子记录集的其他父记录数量,关键是先为每个父记录的子集合生成唯一标识,再基于这个标识统计同组的父记录总数,最终总数减1(排除自身)就是目标结果。

步骤1:生成子集合的唯一标识

通过GROUP_CONCAT将每个父记录的子ID按固定顺序拼接成字符串(必须排序,避免子ID顺序不同导致标识不同),或者用哈希函数(如MD5)将拼接后的字符串转为更简洁的哈希值,确保相同子集合得到完全一致的标识。

步骤2:统计同组父记录数量

基于生成的唯一标识,统计每个标识对应的父记录总数,再对每个父记录计算“总数-1”(排除自身),得到匹配的其他父记录数量。

完整SQL示例

假设表名为parent_child,包含字段parent_id(父记录ID)和child_id(子记录ID):

方案一:直接关联匹配

WITH parent_child_sets AS (
    SELECT 
        parent_id,
        -- 按子ID排序后拼接,保证相同集合的字符串一致
        GROUP_CONCAT(child_id ORDER BY child_id) AS child_set
    FROM parent_child
    GROUP BY parent_id
)
SELECT 
    pcs.parent_id,
    COUNT(other_pcs.parent_id) AS matching_parent_count
FROM parent_child_sets pcs
-- 关联同子集合但不同父ID的记录
LEFT JOIN parent_child_sets other_pcs 
    ON pcs.child_set = other_pcs.child_set 
    AND pcs.parent_id != other_pcs.parent_id
GROUP BY pcs.parent_id
ORDER BY pcs.parent_id;

方案二:先统计组总数再计算

WITH parent_child_sets AS (
    SELECT 
        parent_id,
        MD5(GROUP_CONCAT(child_id ORDER BY child_id)) AS child_set_hash -- 用哈希减少字符串长度
    FROM parent_child
    GROUP BY parent_id
),
set_group_counts AS (
    SELECT 
        child_set_hash,
        COUNT(parent_id) AS total_parent_count
    FROM parent_child_sets
    GROUP BY child_set_hash
)
SELECT 
    pcs.parent_id,
    -- 组总数大于1时减1,否则为0
    CASE WHEN sgcs.total_parent_count > 1 THEN sgcs.total_parent_count - 1 ELSE 0 END AS matching_parent_count
FROM parent_child_sets pcs
JOIN set_group_counts sgcs ON pcs.child_set_hash = sgcs.child_set_hash
ORDER BY pcs.parent_id;

注意事项

  • 若子ID数量较多,GROUP_CONCAT可能超出默认长度限制,需先调整会话参数:SET SESSION group_concat_max_len = 1000000;(根据实际需求设置长度)。
  • 使用哈希函数(如MD5)可以避免长字符串的存储和比较问题,但需注意极低概率的哈希碰撞(业务场景中通常可忽略)。
  • 若存在无任何子记录的父ID,上述查询会将所有无子记录的父ID归为同一组,统计结果为该组总数减1。

内容的提问来源于stack exchange,提问作者Sg8107

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 08:08:13