Reputation: 169
I am working on a report that needs to display people who have not done certain training. I have a query that shows people's names and the raining they've done, and another query that shows the entire list of training.
Query #1:
select distinct a.ID, b.Name, b.Descript, b.Code
from Roster a
join SkillCheckOff b on b.Id = a.ID
order by a.ID, b.Descript
Query #2:
select Descript, Code
from LookupTable
where Type = 'TRTSkillCheckOff'
order by Descript
Final result:
Name Descript
-----------------------
John Training A
Abbie Training A
Mike Training B
...
Basically, if the descript from query #2 is not found from query #1 for each user, the final query needs to display the name and the missing training. Please help.
Based on the answers provided, I think the below query comes close.
with roster as (
select ID
from Roster
),
skills as (
select Descript, Code from LookupTable where Type = 'TRTSkillCheckOff'
)
select r.ID, s.Descript
from roster r cross join skills s
EXCEPT
select name, Descript
from SkillCheckOff
I think using EXCEPT works here.
Upvotes: 0
Views: 322
Reputation: 899
Below the query with CTE and CROSS JOIN:
;WITH CTE_Table AS (
SELECT DISTINCT
A.ID
,B.Name
,B.Descript
FROM
Roster A
INNER JOIN SkillCheckOff B ON B.ID = A.ID
)
,CTE_Lookup AS (
SELECT
L.Name
,L.Descript
FROM
Lookup
WHERE
Type = 'TRTSkillCheckOff'
)
SELECT
C.ID
,C.Name
,C.Descript
FROM
CTE_Table C
CROSS JOIN CTE_Lookup L
WHERE
L.Descript <> C.Descript
ORDER BY
C.ID
,C.Descript
Upvotes: 1
Reputation: 17915
You need to generate all pairs from rosters and skills then match that against the check-off list:
with roster as (
select ID, Name from Roster
), skills as (
select Descript, Code from LookupTable where Type = 'TRTSkillCheckOff'
)
select r.Name, s.Descript
from roster r cross join skills s
left outer join SkillCheckOff k on k.Id = r.Id and k.Code = s.Code
where k.Id is null
order by r.Name, s.Descript;
Upvotes: 1
Reputation: 3257
You can use NOT EXISTS
:
select distinct a.ID, b.Name, b.Descript, b.Code
from Roster a
join SkillCheckOff b on b.Id = a.ID
WHERE NOT EXISTS (
select 1
from LookupTable
where Type = 'TRTSkillCheckOff' AND Descript = b.Descript
)
Upvotes: 1