T-SQL:如何保持左连接但过滤查询

时间:2016-11-09 17:43:14

标签: sql-server tsql reporting-services ssrs-2008

我正在尝试过滤掉特定用户添加的结果,同时保留每天,因为此查询将用于报表中的图表。当我删除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

2 个答案:

答案 0 :(得分:2)

以下是三种方法。当我开始回答这个问题时,我意识到可能会发生微妙的不同事情。可能所有这三个都可行,但第一个可能并不总是有效。

我怀疑你只想进行额外的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;

答案 1 :(得分:2)

当您在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'