Reputation: 2364
I have the following data block -
+-----------+----------+
| 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 |
+-----------+----------+
I want to do a select statement where by I can find all child_id's that belong to parents and group the results, something like -
+-----------+----------+
| parent_id | child_id |
+-----------+----------+
| 1 | 12 & 13 |
| 2 | |
+-----------+----------+
+-----------+----------+
| parent_id | child_id |
+-----------+----------+
| 1 | 12 |
| 2 | |
| 5 | |
+-----------+----------+
+-----------+----------+
| parent_id | child_id |
+-----------+----------+
| 3 | 16 |
| 4 | |
| 5 | |
+-----------+----------+
So parents 1 and 2 both have children 12 and 13. Parents 1,2 and 5 all have 12 as a child, and 3,4 and 5 all have 16 as a child.
Upvotes: 1
Views: 1720
Reputation: 46219
You can try to use cte get a result set which contains your expect parent_id
and child_id
then use FOR XML PATH
combine them with &
.
finally use row_number
window function create row number with CASE WHEN
do condition aggregate function, let only first-row display 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
Result
parent_id child_id
1 12&13
2
Upvotes: 1
Reputation: 50163
I think you want :
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);
Upvotes: 2