"Group By" 子句的 PostgreSQL 问题
PostgreSQL problem with the "Group By" Clause
我有一个 table 在 ORDERED by R_Value Desc
时看起来像这样
请注意,重要的是要了解下面的 table 是 SQL SELECT ordered by R_Value
Id Letter R_Value
1 A 1500
2 A 1400
4 B 800
9 B 700
10 B 600
11 A 400
12 A 200
我希望我的结果集看起来像这样。结果集需要分组3
次。每次,字母从 A 变为 B,反之亦然,一个新的组应该
成立。
Letter Max_RValue
A 1500
B 800
A 400
我已经尝试过各种东西 - lead/lag 函数、分区等,但似乎不可能。一个简单的 Group by(Letter)
显然行不通,因为
所有 'A' 将被放在一组,这不是我想要的。
我的下一步是用一种过程语言来尝试这个,把它转储到一个
中间 table 然后读取结果。在这样做之前,这是否均匀
可能在普通 SQL?
您可以使用 LAG()
window 函数检查每行的 Letter
的先前值,并使用 SUM()
window 函数创建组连续出现的行。
然后每组合计:
SELECT Letter, MAX(R_Value) Max_RValue
FROM (
SELECT *, SUM(flag::int) OVER (ORDER BY R_Value DESC) grp
FROM (
SELECT *, Letter <> LAG(Letter, 1, '') OVER (ORDER BY R_Value DESC) flag
FROM tablename
) t
) t
GROUP BY grp, Letter;
或者,更简单的是 select Letter
更改的行:
SELECT Letter, R_Value
FROM (
SELECT *, LAG(Letter, 1, '') OVER (ORDER BY R_Value DESC) prev_Letter
FROM tablename
) t
WHERE Letter <> prev_Letter;
参见demo。
Forpas 的第二个解决方案还可以,但在 Postgres 中可以更简单地编写为:
select letter, r_value
from (select t.*, lag(letter) over (order by r_value) as prev_letter
from t
) t
where prev_letter is distinct from letter;
我有一个 table 在 ORDERED by R_Value Desc
时看起来像这样
请注意,重要的是要了解下面的 table 是 SQL SELECT ordered by R_Value
Id Letter R_Value
1 A 1500
2 A 1400
4 B 800
9 B 700
10 B 600
11 A 400
12 A 200
我希望我的结果集看起来像这样。结果集需要分组3 次。每次,字母从 A 变为 B,反之亦然,一个新的组应该 成立。
Letter Max_RValue
A 1500
B 800
A 400
我已经尝试过各种东西 - lead/lag 函数、分区等,但似乎不可能。一个简单的 Group by(Letter)
显然行不通,因为
所有 'A' 将被放在一组,这不是我想要的。
我的下一步是用一种过程语言来尝试这个,把它转储到一个 中间 table 然后读取结果。在这样做之前,这是否均匀 可能在普通 SQL?
您可以使用 LAG()
window 函数检查每行的 Letter
的先前值,并使用 SUM()
window 函数创建组连续出现的行。
然后每组合计:
SELECT Letter, MAX(R_Value) Max_RValue
FROM (
SELECT *, SUM(flag::int) OVER (ORDER BY R_Value DESC) grp
FROM (
SELECT *, Letter <> LAG(Letter, 1, '') OVER (ORDER BY R_Value DESC) flag
FROM tablename
) t
) t
GROUP BY grp, Letter;
或者,更简单的是 select Letter
更改的行:
SELECT Letter, R_Value
FROM (
SELECT *, LAG(Letter, 1, '') OVER (ORDER BY R_Value DESC) prev_Letter
FROM tablename
) t
WHERE Letter <> prev_Letter;
参见demo。
Forpas 的第二个解决方案还可以,但在 Postgres 中可以更简单地编写为:
select letter, r_value
from (select t.*, lag(letter) over (order by r_value) as prev_letter
from t
) t
where prev_letter is distinct from letter;