你提到的情况可能涉及更复杂的逻辑,特别是当你需要处理更复杂的分组和排序逻辑时。为了更全面地解决这个问题,我们可以进一步细化查询,以确保涵盖所有可能的情况。
假设你有一个包含以下列的表 my_table
:
id
: 唯一标识符group_id
: 分组标识符value
: 需要处理的值timestamp
: 时间戳,用于确定顺序你希望根据 group_id
分组,并选择每个组的上一个组的最后一个值。以下是一个更详细的示例,展示如何使用窗口函数和子查询来实现这一点。
假设你的表 my_table
包含以下数据:
id | group_id | value | timestamp |
---|---|---|---|
1 | A | 10 | 2023-01-01 10:00:00 |
2 | A | 20 | 2023-01-01 11:00:00 |
3 | B | 30 | 2023-01-01 12:00:00 |
4 | B | 40 | 2023-01-01 13:00:00 |
5 | C | 50 | 2023-01-01 14:00:00 |
6 | C | 60 | 2023-01-01 15:00:00 |
你希望根据 group_id
分组,并选择每个组的上一个组的最后一个值。你可以使用窗口函数和子查询来实现这一点。
WITH ranked_table AS (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY timestamp DESC) AS rn
FROM
my_table
),
last_values AS (
SELECT
group_id,
value AS last_value,
ROW_NUMBER() OVER (ORDER BY group_id) AS group_rank
FROM
ranked_table
WHERE
rn = 1
)
SELECT
t.id,
t.group_id,
t.value,
t.timestamp,
lv.last_value AS current_group_last_value,
LAG(lv.last_value) OVER (ORDER BY lv.group_rank) AS previous_group_last_value
FROM
my_table t
JOIN
last_values lv
ON
t.group_id = lv.group_id
ORDER BY
t.timestamp;
ROW_NUMBER()
窗口函数为每个 group_id
分组的数据按 timestamp
降序排列,并为每一行分配一个行号 rn
。ranked_table
中选择每个 group_id
的最后一个值(即 rn = 1
的行),并为每个组分配一个 group_rank
。my_table
与 last_values
进行连接,以便每行都包含其组的最后一个值。LAG
窗口函数根据 group_rank
的顺序获取上一个组的最后一个值。查询结果将包含每行的 id
、group_id
、value
、timestamp
以及上一个组的最后一个值 previous_group_last_value
。
id | group_id | value | timestamp | current_group_last_value | previous_group_last_value |
---|---|---|---|---|---|
1 | A | 10 | 2023-01-01 10:00:00 | 20 | NULL |
2 | A | 20 | 2023-01-01 11:00:00 | 20 | NULL |
3 | B | 30 | 2023-01-01 12:00:00 | 40 | 20 |
4 | B | 40 | 2023-01-01 13:00:00 | 40 | 20 |
5 | C | 50 | 2023-01-01 14:00:00 | 60 | 40 |
6 | C | 60 |
领取专属 10元无门槛券
手把手带您无忧上云