Full Outer Join 不包括双方的所有记录
Posted
技术标签:
【中文标题】Full Outer Join 不包括双方的所有记录【英文标题】:Full Outer Join Not including all records from both sides 【发布时间】: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.Date
的 NULL
值。 t.compid=270
也应该在ON
中,然后你可以删除t.compid IS NULL
【参考方案1】:
您的WHERE
子句最终从两个表中过滤掉不匹配项,几乎将它们变成INNER JOIN
s(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
子句。
【讨论】:
以上是关于Full Outer Join 不包括双方的所有记录的主要内容,如果未能解决你的问题,请参考以下文章