postgres 11.7中join的错误计数为1

yh2wf1be  于 2021-08-09  发布在  Java
关注(0)|答案(1)|浏览(277)

我遇到了一个微妙的问题 count(*) 以及 join ,希望得到一些确认,我已经正确地知道发生了什么。在后台,我们通常将连续的时间线数据转换为离散的时间段,例如小时。既然我们不希望没有内容的垃圾箱有空隙,我们就用 generate_series 合成我们想要的桶值。如果上午10点没人报名,好吧,我们还是会有结果的。但是,我注意到有时我得到的是1而不是0。我想确认的是:
如果对“网格”系列进行计数,则计数为1;如果对数据表进行计数,则计数为0。
这只与 count ,无其他骨料。
下面的代码设置了一些示例数据来显示我所说的内容:

DROP TABLE IF EXISTS analytics.measurement_table CASCADE;

CREATE TABLE IF NOT EXISTS analytics.measurement_table (
    hour smallint NOT NULL DEFAULT NULL,
    measurement smallint NOT NULL DEFAULT NULL
);

INSERT INTO measurement_table (hour, measurement)
     VALUES ( 0, 1),
            ( 1, 1),  ( 1, 1),
            (10, 2),  (10, 3), (10, 5);

以下是查询的目标结果。我用了12个小时来缩短示例结果。

Hour Count sum
 0    1     1
 1    2     2
 2    0     0
 3    0     0
 4    0     0
 5    0     0
 6    0     0
 7    0     0
 8    0     0
 9    0     0
10    3    10
11    0     0
12    0     0

这可以正常工作:

WITH hour_series AS (
    select * from generate_series (0,12) AS hour
    ) 

    SELECT hour_series.hour,
           count(measurement_table.hour) AS frequency,
           COALESCE(sum(measurement_table.measurement), 0) AS total

      FROM hour_series
LEFT JOIN measurement_table ON (measurement_table.hour = hour_series.hour)

GROUP BY 1
ORDER BY 1

这将在匹配中返回1:

WITH hour_series AS (
    select * from generate_series (0,12) AS hour
    ) 

    SELECT hour_series.hour,
           count(*) AS frequency,
           COALESCE(sum(measurement_table.measurement), 0) AS total

      FROM hour_series
LEFT JOIN measurement_table ON (hour_series.hour = measurement_table.hour)

GROUP BY 1
ORDER BY 1
0   1   1
1   2   2
2   1   0
3   1   0
4   1   0
5   1   0
6   1   0
7   1   0
8   1   0
9   1   0
10  3   10
11  1   0
12  1   0

这两个例子之间的唯一区别是 count 期限:

count(*) -- A result of 1 on no match, and a correct count otherwise.
count(joined to table field) -- 0 on no match, correct count otherwise.

似乎就是这样,你必须明确你在数数据表。否则,由于序列数据只匹配一次,因此计数为1。这是联合的细微差别,还是 count 在博士后?
这会影响到其他的争吵吗?好像不应该。
附笔 generate_series 是有史以来最好的事情。

pxy2qtax

pxy2qtax1#

你正确地解决了问题: count() 根据给定的参数,行为会有所不同。 count(*) 统计属于组的行数。这是不可能的 0 因为一个组中总是至少有一行(否则就没有组)。
另一方面,当给定列名或表达式作为参数时, count() 考虑到任何非- null 值,并忽略 null 价值观。对于您的查询,这允许您区分组中没有匹配项的组 left join 从有匹配项的组中删除表。
请注意,此行为不是特定于postgres的,而是属于标准ansisql规范(我知道的所有数据库都符合该规范)。
底线:
一般情况下,使用 count(*) ; 这样效率更高,因为数据库不需要检查 null s(并向查询的读者说明您只想知道有多少行属于该组)
在像你这样的特殊情况下,请在 count()

相关问题