我有两个要查询的表:pest_counts
它们pests
看起来像:
CREATE TABLE pests(id,name)
AS VALUES
(1,'Thrip'),
(2,'Fungus Gnosts');
CREATE TABLE pest_counts(id,pest_id,date,count)
AS VALUES
(1,1,'2015-01-01'::date,14),
(2,2,'2015-01-02'::date,5);
我想使用 postgresgenerate_series
来显示为日期系列找到的每种害虫的数量:
预期成绩
name | date | count
-------------+------------+-------
Thrip | 2015-01-01 | 14
Thrip | 2015-01-02 | 0
....
Fungus Gnats | 2015-01-01 | 0
Fungus Gnats | 2015-01-02 | 5
...
我知道我需要类似以下的东西,但我不确定如何做剩下的:
SELECT date FROM generate_series('2015-01-01'::date, '2015-12-31'::date, '1 day') date
我通常通过为所有可能的数据点(这里是害虫和日期)建立一个表格来解决这些问题。这可以通过 a 轻松实现
CROSS JOIN
,请参见WITH
下面的查询。然后,作为最后一步,我只是(外部)加入现有的测量值,基于害虫 ID 和日期 - 可选地通过
COALESCE()
.所以,整个查询是:
在SQLFiddle上检查它。
注意:当表格或生成的系列很大时,在
CROSS JOIN
CTE 内部进行可能不是一个好主意。(无论是否有给定日期的数据,它都必须实现所有行)。在这种情况下,应该在FROM
子句中做同样的事情,作为带括号的子连接,而不是当前对data_points
. 这样,规划者可以更好地了解受影响的行以及使用索引的可能性。我在示例中使用 CTE,因为它看起来更简洁。我会建议您下次使用 fiddle.com 以便有一个在线模式可以玩。
generate_series 函数返回一组时间戳,因此您需要将其转换为函数外部的日期。这在当前查询中是必要的,因为它与表中的
timestamp
不匹配。date
pest_counts
我会建议类似的东西: