SQL Query to retrieve parent table records that have a list of child records

I have two tables in the MS SQL Server 2005 database, parent and child, where a parent can be associated with many child records. [Child.parent_id] is associated with [parent.id]. The child table also has a column [foo] I need to return all the records to the parent table, where [child.foo] matches each of the parameters from one to many. For example, I would like all parent records to have the value [child.foo] 'fizz' and the value [child.foo] 'buzz.' I tried the following query, but it returns records that match only one.

SELECT     Parent.ID
FROM         Parent 
INNER JOIN Child ON Parent.ID = Child.parent_id
WHERE     (Child.foo = 'fizz')
UNION ALL
SELECT     Parent_1.ID
FROM         Parent AS Parent_1 
INNER JOIN Child AS Child_1 ON Parent_1.ID = Child_1.parent_id
WHERE     (Child_1.foo = 'buzz')
+3
source share
4

, [ ] "fizz" foo [ ] "buzz" foo. , , .

, , , SQL, , CTE, .

   SELECT DISTINCT Parent.ID
    FROM Parent
    JOIN Child C1 ON Parent.ID = C1.parent_Id
    JOIN Child C2 ON Parent.ID = C2.parent_id
    WHERE C1.foo = 'fizz'
      AND C2.foo = 'buzz'

Edit:
, , , , , , ( + ). :

  • , foo.
  • , , [ ]
  • . , , , , 2 5 foo .

Joel, , , 2 foo.

SELECT Parent.Id
FROM Parent
INNER JOIN Child on Parent.Id = child.parent_id
WHERE Child.foo IN ('fizz', 'buzz')  -- or say, ... IN ('fizz', 'buzz', 'bang', 'dong')
GROUP BY Parent.Id
HAVING COUNT(DISTINCT Child.foo) = 2  -- or 4 ...  
+6

, - .

Select 
    Parent.Id
From Parent
    inner join Child on Parent.Id = child.parent_id
Where 
    Child.foo = 'fizz' or Child.foo = 'buzz'
Group By
    Parent.Id
Having
    count(distinct Child.foo) > 1

script:

Create Table #parent ( id int )
Create Table #child ( parent_id int, foo varchar(32) )

insert into #parent (id) values (1)
insert into #parent (id) values (2)
insert into #parent (id) values (3)

insert into #child (parent_id, foo) values (1, 'buzz')
insert into #child (parent_id, foo) values (2, 'buzz')
insert into #child (parent_id, foo) values (3, 'buzz')
insert into #child (parent_id, foo) values (1, 'fizz')


Select 
    #parent.Id
From #parent
    inner join #child on #parent.id = #child.parent_id
Where 
    #child.foo = 'fizz' or #child.foo = 'buzz'
Group By
    #parent.Id
Having
    count(distinct #child.foo) > 1        

drop table #parent
drop table #child

Id 1.

+5

:

SELECT p.ID
FROM Parent p
WHERE EXISTS
(
    SELECT 1 FROM Child c WHERE c.parent_id = p.ID AND c.foo IN ('fizz','buzz')
)
0

. , "" . , , LIKE IN.

--Parents whose children contain a subset of children

--setup
create table #parent ( id int )
create table #child ( parent_id int, foo varchar(32) )

insert into #parent (id) values (1)
insert into #parent (id) values (2)
insert into #parent (id) values (3)

insert into #child (parent_id, foo) values (1, 'buzz')
insert into #child (parent_id, foo) values (1, 'buzz')
insert into #child (parent_id, foo) values (1, 'fizz')
insert into #child (parent_id, foo) values (2, 'buzz')
insert into #child (parent_id, foo) values (2, 'fizz')
insert into #child (parent_id, foo) values (2, 'bang')
insert into #child (parent_id, foo) values (3, 'buzz')

--create in calling procedure
declare @tblTargets table (strTarget varchar(10))
insert into @tblTargets (strTarget) values ('fizz')
insert into @tblTargets (strTarget) values ('buzz')

--select query to be called in procedure; 
--  pass @tblTargets in as TVP, or create from delimited string via splitter function
select #parent.id       --returns 1 and 2
    from #parent
       inner join #child on #parent.id = #child.parent_id
    where #child.foo in (select strTarget from @tblTargets)
    group by #parent.id
    having count(distinct #child.foo) = (select COUNT(*) from @tblTargets)        

--cleanup
drop table #parent
drop table #child
0
source

Source: https://habr.com/ru/post/1730589/


All Articles