【问题标题】:Full Outer Join Not including all records from both sidesFull Outer Join 不包括双方的所有记录
【发布时间】:2019-10-21 20:50:34
【问题描述】:

我有一个日期从 2000 年到 2029 年的日历表。我在 date=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

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

我在这里错过了什么?

目标
日期           TOTAL_TRIPS
2019-09-01             3
2019-09-02             5
2019-09-03             0 2019-09-04             4
2019-09-05             0 2019-09-06             9

【问题讨论】:

  • 您的 WHERE 将其转换为隐式 INNER JOIN,因为未处理 c.DateNULL 值。 t.compid=270 也应该在ON 中,然后你可以删除t.compid IS NULL

标签: sql sql-server-2012


【解决方案1】:

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

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

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 几乎GROUP BY 一起使用,在这种情况下不需要。
  • COUNT() 不返回NULL,因此不需要COALESCE()
  • first表的过滤确实属于WHERE子句。

【讨论】:

    猜你喜欢
    • 2014-11-12
    • 2021-06-09
    • 2011-09-28
    • 2011-08-14
    • 1970-01-01
    • 2013-03-10
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    相关资源
    最近更新 更多