Postgresql 如何使另一个表中带有where子句的select count(*)返回空行?

Postgresql 如何使另一个表中带有where子句的select count(*)返回空行?,postgresql,Postgresql,我被这个问题困住了: 我有两张桌子: tbl_统计: id | name 1 | Clicks on purchase button 2 | Total logins tbl_统计详细信息: id | stat_id (FK) | date 1 | 2 | 2019-05-10 18:30:00 在postgre上执行以下命令时: SELECT s.name, count(sd.id) AS count FROM tbl_sta

我被这个问题困住了:

我有两张桌子:

tbl_统计:

id   |   name
1    |  Clicks on purchase button
2    |  Total logins
tbl_统计详细信息:

id   |  stat_id (FK) |  date
1    |      2        | 2019-05-10 18:30:00
在postgre上执行以下命令时:

SELECT s.name, count(sd.id) AS count 
FROM tbl_statistics_detailed sd 
RIGHT OUTER JOIN tbl_statistics s ON s.id = sd.stat_id 
WHERE sd.date BETWEEN '2019-05-01 00:00:00' AND '2019-05-21 00:00:00'
GROUP BY sd.stat_id,s.name;
我得到的结果是:

name          |  count
Total logins  |    1
但我想要的是:

name                          |  count
Total logins                  |    1
Clicks on the purchase button |    0
我做错了什么?

嗯,对于不存在的细节,sd.date为null,因此您的WHERE子句不能为true,因为它们将其转换为连接条件。当你这样做的时候,可能会让它变成一个左连接。那更容易阅读

SELECT s.name,
       count(sd.id) count 
       FROM tbl_statistics s
            LEFT JOIN tbl_statistics_detailed sd 
                      ON sd.stat_id = s.id
                         AND sd.date BETWEEN '2019-05-01 00:00:00'
                                             AND '2019-05-21 00:00:00'
       GROUP BY s.name;

您的右侧外部联接在按筛选/分组之前创建以下行:

sd.id | sd.stat_id | sd.date |    s.id   |   s.name
 NULL |  NULL      |  NULL   |    1      |  Clicks on purchase button
  1   |     2      | 5/10    |    2      |  Total logins

这是您想要的,但是WHERE子句会过滤掉第一行。可以检查date是否在所需范围之间,或者date是否为null,它应该为您提供所需的内容,因为您正在执行countsd.id,它应该忽略null值。

为了进一步提高对该问题的理解,当我从该查询中删除where子句时,它会得到我期望的结果,但是我需要日期之间的结果。非常感谢!它工作得很好!但是除了可读性之外,使用左连接而不是右连接有什么区别吗?@MugiGust:欢迎!是的,在任何情况下,结果表中必须出现的那一面显然是不同的。但除此之外,没有。是的,将where条件移动到join条件中比使用null或将其与null一起移动要好