选择所有子项并按父项分组

时间:2018-10-31 15:11:20

标签: sql sql-server group-by

我有以下数据块-

+-----------+----------+
| parent_id | child_id |
+-----------+----------+
|         1 |       11 |
|         1 |       12 |
|         1 |       13 |
|         2 |       12 |
|         2 |       13 |
|         2 |       14 |
|         3 |       15 |
|         3 |       16 |
|         4 |       16 |
|         5 |       12 |
|         5 |       16 |
+-----------+----------+

我想做一个选择语句,通过它我可以找到所有属于父母的child_id并将结果分组,就像-

+-----------+----------+
| parent_id | child_id |
+-----------+----------+
|         1 | 12 & 13  |
|         2 |          |
+-----------+----------+ 
+-----------+----------+
| parent_id | child_id |
+-----------+----------+
|         1 |      12  |
|         2 |          |
|         5 |          |
+-----------+----------+
+-----------+----------+
| parent_id | child_id |
+-----------+----------+
|         3 |       16 |
|         4 |          |
|         5 |          |
+-----------+----------+

因此,父母 1 2 都有孩子 12 13 。 父母 1,2和5 的孩子均为 12 , 和 3,4和5 都是 16 的孩子。

2 个答案:

答案 0 :(得分:2)

我想你想要

SELECT t.*
FROM table t 
WHERE EXISTS (SELECT 1 FROM table t1 WHERE t1.child_id = t.child_id AND t1.parent_id <> t.parent_id);

答案 1 :(得分:1)

您可以尝试使用cte获取包含期望parent_idchild_id的结果集,然后将FOR XML PATH&结合使用。

最后使用row_number窗口函数和CASE WHEN创建行号做条件集合函数,只让第一行显示child_id

;with cte as (
    SELECT t1.*
    FROM T t1 
    where 
       EXISTS (SELECT 1 FROM T tt WHERE t1.child_id = tt.child_id AND t1.parent_id <> tt.parent_id)
    AND 
       t1.parent_id in (1,2) --add you want to get parent_id id
), cte1 as (
     SELECT 
      distinct parent_id,
      STUFF((
         select  '&' + CAST(tt.child_id AS VARCHAR(MAX))  
         from cte tt 
         where t1.parent_id = tt.parent_id 
        FOR XML PATH(''),TYPE).value('.','VARCHAR(MAX)')
      ,1,1,'') AS child_id
     FROM cte t1
) 
SELECT parent_id,(case when rn = 1 then child_id else '' end) child_id
FROM (
   select *,row_number() over(order by parent_id) rn
   from cte1
) t1

Sqlfiddle

结果

parent_id   child_id
1           12&13
2