SQl Server查询按组查找缺失的行

时间:2017-06-15 20:09:41

标签: sql-server

我在SQL Server 2016中工作。我有两个表--A和B.它们的示例如下:

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

我想显示表A中哪些产品和天数缺少作业实例,如表B所定义。例如,我想要返回:

Product       Day           Job
x             2017-06-14    3
y             2017-06-15    2

我正在努力搞清楚查询。我不能直接FROM A RIGHT JOIN B ON B.Product = A.Product AND B.Job = A.Job WHERE A.Job IS NULL,因为这与Day无关。这几乎就像我需要白天砍掉桌子A并多次加入桌子B(每天一次),但多次加入可能是一个坏主意。如何实现我想要的输出?

1 个答案:

答案 0 :(得分:1)

您需要使用所有可能日期的列表作为另一个连接谓词。在这个例子中,我创建了一个所有日期的cte。然后,您可以列出所有日期的所有工作。从那里它是一个简单的左连接到一个缺少的值。

注意我是如何创建表并用样本数据填充它们的。这是您将来发布样本数据的方法。让那些想要帮助的人变得容易多了。 :)

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
;