Reputation: 5
I'm trying to query a table named DeviceGroups
that contains 2 columns, MachineID
and GroupID
. Here's an example
MachineID GroupID
------------------
1 A1
1 A3
2 A2
3 A2
3 A3
4 A4
4 A5
5 A3
I need to show all MachineID's that contain GroupID A1 or A2, with a separate column that will give a Yes/No if that MachineID also contains A3. Here's the expected result:
MachineID GroupID ContainsA3?
------------------------------
1 A1 Yes
2 A2 No
3 A2 Yes
Notice MachineIDs 4 and 5 are not listed because they does not contain A1 or A2, even though MachineID 5 contains A3. I cannot create a WHERE clause to filter only A1 and A2 because all results will show ContainsA3? as false, and if I include A3 then MachineID 5 will appear with GroupID as NULL which is also not permitted. Any ideas? Here is where I got stuck:
SELECT MachineID,
CASE WHEN GroupID = 3 then "Yes" Else "No" END AS [ContainsA3?]
FROM DeviceGroups
And here's the result:
MachineID ContainsA3?
-----------------
1 No
1 Yes
2 No
3 No
3 Yes
4 No
4 No
5 Yes
If I add a WHERE clause:
SELECT MachineID,
CASE WHEN GroupID = 3 then "Yes" Else "No" END AS [ContainsA3?]
FROM DeviceGroups
WHERE GroupID = 3
MachineID ContainsA3?
-----------------
1 Yes
3 Yes
5 Yes
Upvotes: 0
Views: 49
Reputation: 1702
create table #tbl (
mID int,
gID varchar(2) )
insert into #tbl
values
(1, 'A1'),
(1, 'A3'),
(2, 'A2'),
(3, 'A2'),
(3, 'A3'),
(4, 'A4'),
(4, 'A5'),
(5, 'A3')
select a.*, case when b.gID is not null then 'Yes' else 'No' end as ContainsA3
from #tbl a
left join #tbl b
on b.mID = a.mID
and b.gID = 'A3'
where a.gID in ('A1','A2')
mID gID ContainsA3
1 A1 Yes
2 A2 No
3 A2 Yes
Upvotes: 0
Reputation: 39
From what I undertand a subquery will do the job :
SELECT MachineID,
CASE WHEN GroupID in ('A1','A2')
and 'A3' in (select GroupID from DeviceGroups as dv
where DeviceGroups.MachineID = dv.MachineID)
then 'Yes' Else 'No' END AS [ContainsA3?]
FROM DeviceGroups
Upvotes: 0
Reputation: 32445
You can use a sub query
SELECT groups.MachineID
, ISNULL(
(SELECT 'Yes' FROM DeviceGroups
WHERE MachineID = groups.MachineID AND GroupID = 3)
, 'No'
) AS [ContainsA3?]
FROM DeviceGroups groups
WHERE groups.GroupID IN (1, 2)
GROUP BY groups.MachineID
Upvotes: 2
Reputation: 222582
Consider:
select
MachineID,
max(case when GroupID in ('A1', 'A2') then GroupID end) GroupID,
max(case when GroupID = 'A3' then 'Yes' else 'No' end) ContainsA3
from mytable
where GroupID in ('A1', 'A2', 'A3')
group by MachineID
having max(case when GroupID in ('A1', 'A2') then 1 end) = 1
The idea is to use the where
clause to filter on groups A1, A2, and A3, aggregate by machine, and use the having
clause to ensure that either A1 or A2 was seen. The rest is conditional aggregation in the select
clause.
Upvotes: 0