有人能解释一下为什么这两个查询的输出不同吗?试着理解潜在的逻辑。
查询-1
select u.id,
(count(c.id)) comment_count
from users u
left join comments c
on u.id = c.user_id
and c.created_at between '2020-01-01' and '2020-01-31'
group by 1
order by comment_count desc
字符串
查询2
select u.id,
(count(c.id)) comment_count
from users u
left join comments c
on u.id = c.user_id
where c.created_at between '2020-01-01' and '2020-01-31'
group by 1
order by comment_count desc
型
1条答案
按热度按时间ryevplcw1#
这是sql最尖锐的角落之一,也是人们最常犯的错误。
不同的是这个条件
c.created_at between '2020-01-01' and '2020-01-31'
在第一个JOIN predicate
ON .. AND ...
中应用,但在第二个WHERE predicate 中应用。TLDR -查询1实际上执行了一个LEFT JOIN。查询2在功能上是一个INNER JOIN。如果你在WHERE子句中对表B有一个过滤器(除了NULL),那么你是否输入LEFT JOIN并不重要,它仍然会表现得像一个INNER JOIN。
一个粗略的解释是,在LEFT JOIN子句中应用的过滤器应用于外部表。但是在WHERE子句中应用的过滤器应用于连接的结果。对于INNER JOIN,这不会影响任何东西,但是对于LEFT JOIN很重要。
举个例子
字符串
所以如果我们加入
型
结果集将是
型
因为在{3,C}上找不到匹配项。
因此,当我们在JOIN中添加B_othervalue = 'Y'时,
型
结果是
型
但是,当B_othervalue = 'Y'条件在WHERE子句中时,
型
我们得到
型