繁体   English   中英

PostgreSQL 填写外连接中的空白

[英]PostgreSQL fill in the blanks in an outer join

外部连接“填空”

我在 PostgreSQL 数据库中有一对主从表,其中主表“samples”有一些样本,每个样本都有时间戳。 详细表“sample_values”在任何给定的样本时间戳中都有一些参数的一些值。

我的查询

SELECT s.sample_id, s.sample_time, v.parameter_id, v.sample_value
FROM samples s LEFT OUTER JOIN sample_values v ON v.sample_id=s.sample_id
ORDER BY s.sample_id, v.parameter_id;

回报(如预期):

样品编号 采样时间 参数_id 样本值
1个 2023-01-13T01:00:00.000Z 1个 1.23
1个 2023-01-13T01:00:00.000Z 2个 4.98
2个 2023-01-13T01:01:00.000Z
3个 2023-01-13T01:02:00.000Z
4个 2023-01-13T01:03:00.000Z
5个 2023-01-13T01:04:00.000Z 2个 6.08
6个 2023-01-13T01:05:00.000Z
7 2023-01-13T01:06:00.000Z 1个 1.89
8个 2023-01-13T01:07:00.000Z
9 2023-01-13T01:08:00.000Z
10 2023-01-13T01:09:00.000Z
11 2023-01-13T01:10:00.000Z
12 2023-01-13T01:11:00.000Z
13 2023-01-13T01:12:00.000Z
14 2023-01-13T01:13:00.000Z
15 2023-01-13T01:14:00.000Z 1个 2.11
16 2023-01-13T01:15:00.000Z
17 2023-01-13T01:16:00.000Z
18 2023-01-13T01:17:00.000Z
19 2023-01-13T01:18:00.000Z 2个 3.57
20 2023-01-13T01:19:00.000Z
21 2023-01-13T01:20:00.000Z
22 2023-01-13T01:21:00.000Z
23 2023-01-13T01:22:00.000Z 1个 3.21
23 2023-01-13T01:22:00.000Z 2个 5.31

我如何编写一个查询,每个参数的每个时间戳返回一行,其中 sample_value 是该参数的“最新已知”sample_value,如下所示:

样品编号 采样时间 参数_id 样本值
1个 2023-01-13T01:00:00.000Z 1个 1.23
1个 2023-01-13T01:00:00.000Z 2个 4.98
2个 2023-01-13T01:01:00.000Z 1个 1.23
2个 2023-01-13T01:01:00.000Z 2个 4.98
3个 2023-01-13T01:02:00.000Z 1个 1.23
3个 2023-01-13T01:02:00.000Z 2个 4.98
4个 2023-01-13T01:03:00.000Z 1个 1.23
4个 2023-01-13T01:03:00.000Z 2个 4.98
5个 2023-01-13T01:04:00.000Z 1个 1.23
5个 2023-01-13T01:04:00.000Z 2个 6.08
6个 2023-01-13T01:05:00.000Z 1个 1.23
6个 2023-01-13T01:05:00.000Z 2个 6.08
7 2023-01-13T01:06:00.000Z 1个 1.89
7 2023-01-13T01:06:00.000Z 2个 6.08
8个 2023-01-13T01:07:00.000Z 1个 1.89
8个 2023-01-13T01:07:00.000Z 2个 6.08

在 DB Fiddle 上查看

我无法理解 LAST_VALUE function(如果这甚至是正确的工具?):

LAST_VALUE ( expression )  
OVER ( 
    [PARTITION BY partition_expression, ... ]
    ORDER BY sort_expression [ASC | DESC], ...
)

首先,每个样本 ID 需要两行。 您可以通过将样本值与不同数量的参数交叉连接来实现,并确保在左连接中也满足参数条件。

...
FROM samples s
CROSS JOIN (SELECT DISTINCT parameter_id FROM sample_values) p
LEFT JOIN sample_values v 
       ON v.sample_id = s.sample_id AND v.parameter_id = p.parameter_id
...

除此之外,您使用LAST_VALUE function 的直觉是正确的。 问题是PostgreSQL 在其当前版本之前无法忽略 null 值 此问题的唯一解决方法是在您的 parameter_ids 和 sample_value 上生成分区(每个分区将包含一个非空值和其他 null 值),然后从每个分区中获取最大值。

WITH cte AS (
    SELECT s.sample_id, s.sample_time, p.parameter_id, v.sample_value,
           COUNT(v.sample_value) OVER(
               PARTITION BY p.parameter_id 
               ORDER     BY s.sample_id
           ) AS partitions
    FROM samples s
    CROSS JOIN (SELECT DISTINCT parameter_id FROM sample_values) p
    LEFT JOIN sample_values v 
           ON v.sample_id = s.sample_id AND v.parameter_id = p.parameter_id
)
SELECT sample_id, sample_time, parameter_id, 
       COALESCE(sample_value, 
                MAX(sample_value) OVER (PARTITION BY parameter_id, partitions)
       ) AS sample_value
FROM cte
ORDER BY sample_id, parameter_id

此处查看演示。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM