[英]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 |
我无法理解 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.