Reputation: 2099
I am working in SQL Server 2016. I have 2 tables -- A and B. A sample of them is as follows:
A:
Product Day Job
x 2017-06-15 1
x 2017-06-15 2
x 2017-06-15 3
x 2017-06-14 1
x 2017-06-14 2
y 2017-06-15 1
y 2017-06-14 1
y 2017-06-14 2
B:
Product Job
x 1
x 2
x 3
y 1
y 2
I want to show which Products and Days in table A are missing Job instances, as defined by table B. So, for example, I want to return:
Product Day Job
x 2017-06-14 3
y 2017-06-15 2
I'm struggling with figuring out the query. I can't do a straight FROM A RIGHT JOIN B ON B.Product = A.Product AND B.Job = A.Job WHERE A.Job IS NULL
, since that is independent of Day
. It's almost as if I need to chop up table A by day and join it against table B multiple times (once for each day), but joining multiple times is probably a bad idea. How can I achieve the output I want?
Upvotes: 0
Views: 303
Reputation: 33571
You need to use a list of all the possible dates as another join predicate. In this example I created a cte of all the dates. Then you can get a listing all all jobs for all dates. From there it is a simple left join to a for the missing values.
Notice how I created tables and populated them with sample data. This is how you should post your sample data in the future. Makes it a lot easier for those trying to help. :)
DECLARE @a TABLE
(
Product CHAR(1)
, JobDay DATE
, Job TINYINT
)
INSERT @a
(
Product,
JobDay,
Job
)
VALUES
('x', '2017-06-15', 1)
,('x', '2017-06-15', 2)
,('x', '2017-06-15', 3)
,('x', '2017-06-14', 1)
,('x', '2017-06-14', 2)
,('y', '2017-06-15', 1)
,('y', '2017-06-14', 1)
,('y', '2017-06-14', 2)
DECLARE @b TABLE
(
Product CHAR(1)
, Job tinyint
)
INSERT @b
(
Product,
Job
)
VALUES
('x', 1)
,('x', 2)
,('x', 3)
,('y', 1)
,('y', 2)
;
WITH AllDates AS
(
SELECT DISTINCT JobDay
FROM @a
)
SELECT b.Product
, ad.JobDay
, b.Job
FROM @b b
CROSS JOIN AllDates ad
LEFT JOIN @a a ON a.Product = b.Product
AND a.Job = b.Job
AND a.JobDay = ad.JobDay
WHERE a.Job IS NULL
;
Upvotes: 2