T-SQL:如何保持左连接但过滤查询
T-SQL: How to keep left join but filter query
我正在尝试过滤掉由特定用户添加的结果,同时保留每一天,因为此查询将用于报告中的图表。当我删除 t2.createdBy <> 21
时,我得到了所有日期,但我还需要由此过滤的结果是正确的。
查询:
SELECT
t1.DateFull, COUNT(t2.ContainerWashedDate) as Washes
FROM
DateLookup t1
LEFT JOIN
factContainerWash t2 ON t1.Datefull = t2.ContainerWashedDate
WHERE
(t1.DateFull >= '10/5/2016')
AND (t1.DateFull <= '11/9/2016')
AND t2.createdBy <> 21
GROUP BY
t1.DateFull
ORDER BY
DateFull
结果:
DateFull | Washes
-------------------------+-------
2016-10-05 00:00:00.000 | 1231
2016-10-06 00:00:00.000 | 466
2016-10-10 00:00:00.000 | 84
2016-10-12 00:00:00.000 | 75
预期结果:
DateFull | Washes
-------------------------+-------
2016-10-05 00:00:00.000 | 1231
2016-10-06 00:00:00.000 | 466
2016-10-07 00:00:00.000 | 655
2016-10-08 00:00:00.000 | 23
以下是三种方法。当我开始回答这个问题时,我意识到可能会发生一些微妙的不同的事情。可能所有这三个都有效,但第一个可能并不总是有效。
我怀疑您只是想要一个额外的 NULL
比较:
SELECT t1.DateFull, COUNT(t2.ContainerWashedDate) as Washes
FROM DateLookup t1 LEFT JOIN
factContainerWash t2
ON t1.Datefull = t2.ContainerWashedDate
WHERE t1.DateFull >= '2016-10-05' and
t1.DateFull <= '2016-11-09' and
(t2.createdBy <> 21 or t2.createdBy is null)
GROUP BY t1.DateFull
ORDER BY DateFull;
或者,或者,使用条件聚合:
SELECT t1.DateFull,
COUNT(CASE WHEN createdBy <> 21 THEN t2.ContainerWashedDate END) as Washes
FROM DateLookup t1 LEFT JOIN
factContainerWash t2
ON t1.Datefull = t2.ContainerWashedDate
WHERE t1.DateFull >= '2016-10-05' and
t1.DateFull <= '2016-11-09'
GROUP BY t1.DateFull
ORDER BY DateFull;
也可以将条件移动到 ON
子句来完成您需要的工作:
SELECT t1.DateFull,
COUNT(t2.ContainerWashedDate) as Washes
FROM DateLookup t1 LEFT JOIN
factContainerWash t2
ON t1.Datefull = t2.ContainerWashedDate AND t2.createdBy <> 21
WHERE t1.DateFull >= '2016-10-05' and
t1.DateFull <= '2016-11-09'
GROUP BY t1.DateFull
ORDER BY DateFull;
当您在 WHERE 子句中使用 t2.CreatedBy 时,您使 LEFT JOIN 变成了 INNER JOIN。这样的事情怎么样:
SELECT
t1.DateFull
, COALESCE(t2.Washes, 0) AS Washes
FROM
(
SELECT
ContainerWahsedDate
, COUNT(ContainerWahsedDate) AS Washes
FROM
factConainerWash
WHERE
ContainerWahsedDate BETWEEN '2016-10-05' AND '2016-11-09'
AND CreatedBy <> 21
GROUP BY
ContainerWashedDate
) t2
LEFT JOIN DateLookup t1 ON t1.DateFull = t2.ContainerWahsedDate
WHERE
t2.DateFull BETWEEN '2016-10-05' AND '2016-11-09'
我正在尝试过滤掉由特定用户添加的结果,同时保留每一天,因为此查询将用于报告中的图表。当我删除 t2.createdBy <> 21
时,我得到了所有日期,但我还需要由此过滤的结果是正确的。
查询:
SELECT
t1.DateFull, COUNT(t2.ContainerWashedDate) as Washes
FROM
DateLookup t1
LEFT JOIN
factContainerWash t2 ON t1.Datefull = t2.ContainerWashedDate
WHERE
(t1.DateFull >= '10/5/2016')
AND (t1.DateFull <= '11/9/2016')
AND t2.createdBy <> 21
GROUP BY
t1.DateFull
ORDER BY
DateFull
结果:
DateFull | Washes
-------------------------+-------
2016-10-05 00:00:00.000 | 1231
2016-10-06 00:00:00.000 | 466
2016-10-10 00:00:00.000 | 84
2016-10-12 00:00:00.000 | 75
预期结果:
DateFull | Washes
-------------------------+-------
2016-10-05 00:00:00.000 | 1231
2016-10-06 00:00:00.000 | 466
2016-10-07 00:00:00.000 | 655
2016-10-08 00:00:00.000 | 23
以下是三种方法。当我开始回答这个问题时,我意识到可能会发生一些微妙的不同的事情。可能所有这三个都有效,但第一个可能并不总是有效。
我怀疑您只是想要一个额外的 NULL
比较:
SELECT t1.DateFull, COUNT(t2.ContainerWashedDate) as Washes
FROM DateLookup t1 LEFT JOIN
factContainerWash t2
ON t1.Datefull = t2.ContainerWashedDate
WHERE t1.DateFull >= '2016-10-05' and
t1.DateFull <= '2016-11-09' and
(t2.createdBy <> 21 or t2.createdBy is null)
GROUP BY t1.DateFull
ORDER BY DateFull;
或者,或者,使用条件聚合:
SELECT t1.DateFull,
COUNT(CASE WHEN createdBy <> 21 THEN t2.ContainerWashedDate END) as Washes
FROM DateLookup t1 LEFT JOIN
factContainerWash t2
ON t1.Datefull = t2.ContainerWashedDate
WHERE t1.DateFull >= '2016-10-05' and
t1.DateFull <= '2016-11-09'
GROUP BY t1.DateFull
ORDER BY DateFull;
也可以将条件移动到 ON
子句来完成您需要的工作:
SELECT t1.DateFull,
COUNT(t2.ContainerWashedDate) as Washes
FROM DateLookup t1 LEFT JOIN
factContainerWash t2
ON t1.Datefull = t2.ContainerWashedDate AND t2.createdBy <> 21
WHERE t1.DateFull >= '2016-10-05' and
t1.DateFull <= '2016-11-09'
GROUP BY t1.DateFull
ORDER BY DateFull;
当您在 WHERE 子句中使用 t2.CreatedBy 时,您使 LEFT JOIN 变成了 INNER JOIN。这样的事情怎么样:
SELECT
t1.DateFull
, COALESCE(t2.Washes, 0) AS Washes
FROM
(
SELECT
ContainerWahsedDate
, COUNT(ContainerWahsedDate) AS Washes
FROM
factConainerWash
WHERE
ContainerWahsedDate BETWEEN '2016-10-05' AND '2016-11-09'
AND CreatedBy <> 21
GROUP BY
ContainerWashedDate
) t2
LEFT JOIN DateLookup t1 ON t1.DateFull = t2.ContainerWahsedDate
WHERE
t2.DateFull BETWEEN '2016-10-05' AND '2016-11-09'