缺少具有左连接和count()的行所需的说明

Dea*_*key 12 sql postgresql aggregate-functions

有人可以帮我理解当我将WHERE子句添加到具有COUNT(*)LEFT JOIN的查询时发生的以下行为吗?

我有两张桌子:

TABLE 1: customers
customer_id | name
------------------
1 | Bob
2 | James
3 | Fred

TABLE 2: orders
order_id | customer_id | order_timestamp
----------------------------------------
1000 | 1 | 2011-01-01 00:00
1001 | 1 | 2011-01-05 00:00
1002 | 2 | 2011-01-10 00:00
Run Code Online (Sandbox Code Playgroud)

现在,以下查询告诉我每个客户下了多少订单:

select c.customer_id, count(o.order_id)
from customers c
left join orders o using (customer_id)
group by 1

customer_id | count
-------------------
1 | 2
2 | 1
3 | 0
Run Code Online (Sandbox Code Playgroud)

这很有用但是如果我在查询中添加一个WHERE子句,即使我正在进行LEFT JOIN,查询也不会为没有下任何订单的客户输出零数:

select c.customer_id, count(o.order_id)
from customers c
left join orders o using (customer_id)
where o.order_timestamp >= '2011-01-05'
group by 1

customer_id | count
-------------------
1 | 1
2 | 1
Run Code Online (Sandbox Code Playgroud)

现在,如果我将WHERE条件作为LEFT JOIN的一部分移动,如下所示,我会为没有下订单的客户收回零点数:

select c.customer_id, count(o.order_id)
from customers c
left join orders o on (c.customer_id = o.customer_id) and (o.order_timestamp >= '2011-01-05')
group by 1
Run Code Online (Sandbox Code Playgroud)

我很困惑为什么第二个查询不起作用,但第三个查询不起作用?有人可以请我解释一下吗?也不确定这是否重要,但我正在使用postgres.谢谢!

Chr*_*fer 7

这是因为NULL不大于或等于任何东西; 如果将WHERE子句更改为where o.order_timestamp is null or o.order_timestamp >= '2011-01-05'then,则将获得与join子句限制相同的行为.

请注意 - 我会建议使用join子句方法,因为它与您尝试的方法更紧密地匹配.此外,上面提到的WHERE子句的更改仅在order_timestamp列不可为空时才有效 - 如果是,那么您应该使用不同的列进行空检查(例如,where o.primarykey is null or o.order_timestamp >= '2011-01-05').


OMG*_*ies 5

在处理OUTER连接(RIGHT,LEFT)时,过滤条件的放置很重要.在JOIN之前应用OUTER JOIN的ON子句中的标准; WHERE子句中的条件在JOIN 之后应用- 应用于使用JOIN的结果集.

   SELECT c.customer_id, 
          COUNT(o.order_id)
     FROM CUSTOMERS c
LEFT JOIN ORDERS o ON o.customer_id - c.customer_id
                  AND o.order_timestamp >= '2011-01-05'
 GROUP BY c.customer_id
Run Code Online (Sandbox Code Playgroud)

使用引用SELECT子句中列的数字位置的数值的常数,不建议使用.如果有人更改了查询 - 例如添加列 - 则可能会严重影响您的查询.