Reputation: 519
I'm trying to determine whether a computer in our organization has certain applications assigned to it. The problem I'm having is that the left join is listing duplicates, listing out every assignment rather than ideally listing the computer name, then 1 if the app(s) is assinged to it or 0 if it doesn't have any of those apps assigned to it. What approach should I take to accomplish this?
The app list can have up to 100+ applications so I need to use an IN. I am unable to modify any of the DB columns.
http://sqlfiddle.com/#!9/a5a387/5
Any help is greatly appreciated!!!
CREATE TABLE macs
(`wsid` int, `mach_name` varchar(20))
;
CREATE TABLE assignments
(`wsid` int, `adp_id` int)
;
INSERT INTO macs
(`wsid`, `mach_name`)
VALUES
(1, 'computer1'),
(2, 'computer2'),
(3, 'computer3')
;
INSERT INTO assignments
(`wsid`, `adp_id`)
VALUES
(1, '100'),
(1, '101'),
(1, '103'),
(2, '100'),
(2, '101'),
(3, '100'),
(3, '101'),
(3, '103')
;
and the query:
select mach_name,
CASE
WHEN b.adp_id in(103) THEN 1 ELSE 0 END
from macs a
left join assignments b on a.wsid = b.wsid
Upvotes: 2
Views: 40
Reputation: 295
You could use a correlated sub-query,
SELECT mach_name, COALESCE((SELECT 1 FROM assignments WHERE wsid=m.wsid AND adp_id=103 LIMIT 1), 0) FROM macs m
then COALESCE
the potentially NULL
value to 0
. This is a bit more compact than a CASE
statement.
The reason that the OUTER JOIN
is returning multiple rows is because rows on the left side of the JOIN
can occur multiple times in the right hand side. I.e. there is only one of each machine, but machines can have many assignments. So there are multiple rows that contain a given machine which satisfy your join predicate.
Both the CASE
answer and my answer select from the macs
table once, and select the result into a column for each machine.
Upvotes: 0
Reputation: 1269953
Use exists
:
select m.*,
(case when exists (select 1 from assignments a where a.wsid = w.wsid and a.adp_id in (103)
then 1 else 0
end) as flag
from macs m;
Upvotes: 1