完全外部联接不包括双方的所有记录

时间:2019-10-21 20:50:34

标签: sql sql-server-2012

我有一个日历表,其日期从2000年到2029年。我已经对日期= tdate的数据表进行了完全外部联接。我的目标是按日期计算旅行次数,如果没有旅行,则显示零。但是,不会显示所有日期。如果数据表中没有行程日期,则“日历”表中的日期根本不会显示。我从未见过这种情况。我尝试将其更改为左外连接,该连接也不起作用。实际查询如下。

    SELECT DISTINCT c.DATE,
        COALESCE(COUNT(t.TripID), 0) AS tripCount
    FROM dbo.Calendar c
    FULL OUTER JOIN dbo.TripsMade t ON c.DATE = CONVERT(DATE, t.tripdate, 126)
    WHERE (c.DATE BETWEEN '2019-09-01' AND '2019-09-30' )
      AND (t.compid = 270 OR t.compid IS NULL)
    GROUP BY c.DATE
    ORDER BY c.DATE

如果我从“日历表”中选择所有日期,则它们都在那里。数据表中缺少日期,并且总是会有一些缺失。我需要所有日期都显示在此报告上,如果“数据表”端没有相关记录,则显示为零。

我在这里想念什么?

目标
DATE TOTAL_TRIPS
2019-09-01``3
2019-09-02 5
2019-09-03 0 <==此行目前完全缺失
2019-09-04 44
2019-09-05``0 <==该行当前完全丢失
2019-09-06的9

1 个答案:

答案 0 :(得分:0)

您的WHERE子句最终从两个表中过滤掉不匹配项,几乎将它们变成INNER JOIN s个(与t上的条件有点复杂。

我认为您不需要FULL JOIN。我怀疑您想在LEFT JOIN子句中使用ON过滤(用于第二张表):

SELECT c.Date, COUNT(t.TripID) AS tripCount
FROM dbo.Calendar c LEFT OUTER JOIN
     dbo.TripsMade t
     ON c.date = CONVERT(DATE, t.tripdate, 126) AND
        t.compid = 270
WHERE c.Date BETWEEN '2019-09-01' AND '2019-09-30'
GROUP BY c.Date
ORDER BY c.Date;

如果compid实际上可以接受NULL个值,并且您需要它们,请使用(t.compid = 270 OR t.compid IS NULL)。但是,我怀疑那不是您想要的。 NULL仅表示JOIN上的不匹配项。

注意:

  • SELECT DISTINCT几乎从未使用过{em> ,GROUP BY也不需要,
  • COUNT()不返回NULL,因此不需要COALESCE()
  • first 表的过滤确实属于WHERE子句。