从 window 行中获取最大值作为所有行的新列
Get max value from a window of rows as new column for all rows
| col 1 | col 2 | col 3 |
|-------|-------|-------|
| 67458 | ADM | 1008 |
| 67458 | ADM | 1009 |
| 67458 | SKI | 1009 |
| 67458 | LIS | 1010 |
| 67458 | TOU | 1121 |
如何在 col2='ADM'
时获取 col3
的最大值并将其用作其余记录的值?
预期结果:
| col 1 | col 2 | col 3 | col 4 |
|-------|-------|-------|-------|
| 67458 | ADM | 1008 | 1009 |
| 67458 | ADM | 1009 | 1009 |
| 67458 | SKI | 1009 | 1009 |
| 67458 | LIS | 1010 | 1009 |
| 67458 | TOU | 1121 | 1009 |
我知道如何使用子选择和所有方法来做到这一点。 col4
将是一个伪列,用于下游的 JOIN 和其他内容。
我尝试了以下但它填充 1121 而不是 1009:
MAX(col3) OVER (PARTITION BY col1 (CASE WHEN col2='ADM' THEN col2 END) ORDER BY col1)
你可以使用关联子查询:
select t.*,
(select max(t1.col3) from table t1 where t1.col1 = t.col1 and t1.col2 = 'ADM') as col4
from table t;
使用window函数:
select t.*,
max(col3) filter (where col2 = 'ADM') over (partition by col1) as col4
from t;
在 Redshift 中,您可能必须使用 case
:
select t.*,
max(case when col2 = 'ADM' then col3 end) over (partition by col1) as col4
from t;
您可以在 SELECT
中使用子查询来获取该值。
如果您介意一次又一次地执行它并交叉连接它,则可以将该 suq 查询存储在一个变量中。
架构 (PostgreSQL v10.0)
CREATE TABLE test (
"col 1" INTEGER,
"col 2" VARCHAR(3),
"col 3" INTEGER
);
INSERT INTO test
("col 1", "col 2", "col 3")
VALUES
('67458', 'ADM', '1008'),
('67458', 'ADM', '1009'),
('67458', 'SKI', '1009'),
('67458', 'LIS', '1010'),
('67458', 'TOU', '1121');
查询#1
SELECT MAX("col 3") AS "col 4" INTO col4 FROM test t2 WHERE t2."col 2" = 'ADM';
没有要显示的结果。
查询 #2
SELECT "col 1",
"col 2",
"col 3",
"col 4"
FROM test
CROSS JOIN
col4;
输出
| col 1 | col 2 | col 3 | col 4 |
| ----- | ----- | ----- | ----- |
| 67458 | ADM | 1008 | 1009 |
| 67458 | ADM | 1009 | 1009 |
| 67458 | SKI | 1009 | 1009 |
| 67458 | LIS | 1010 | 1009 |
| 67458 | TOU | 1121 | 1009 |
SELECT t.*, max(CASE WHEN col2 = 'ADM' THEN col3 END) OVER (PARTITION BY col1) AS col4
FROM tbl t;
聚合 FILTER
子句是在 PostgreSQL 9.4 中引入的,对此非常有用。但是 Redshift 不是 Postgres,Postgres 中后来添加的大部分内容在那里不受支持。比较:
- How can I simplify this game statistics query?
| col 1 | col 2 | col 3 |
|-------|-------|-------|
| 67458 | ADM | 1008 |
| 67458 | ADM | 1009 |
| 67458 | SKI | 1009 |
| 67458 | LIS | 1010 |
| 67458 | TOU | 1121 |
如何在 col2='ADM'
时获取 col3
的最大值并将其用作其余记录的值?
预期结果:
| col 1 | col 2 | col 3 | col 4 |
|-------|-------|-------|-------|
| 67458 | ADM | 1008 | 1009 |
| 67458 | ADM | 1009 | 1009 |
| 67458 | SKI | 1009 | 1009 |
| 67458 | LIS | 1010 | 1009 |
| 67458 | TOU | 1121 | 1009 |
我知道如何使用子选择和所有方法来做到这一点。 col4
将是一个伪列,用于下游的 JOIN 和其他内容。
我尝试了以下但它填充 1121 而不是 1009:
MAX(col3) OVER (PARTITION BY col1 (CASE WHEN col2='ADM' THEN col2 END) ORDER BY col1)
你可以使用关联子查询:
select t.*,
(select max(t1.col3) from table t1 where t1.col1 = t.col1 and t1.col2 = 'ADM') as col4
from table t;
使用window函数:
select t.*,
max(col3) filter (where col2 = 'ADM') over (partition by col1) as col4
from t;
在 Redshift 中,您可能必须使用 case
:
select t.*,
max(case when col2 = 'ADM' then col3 end) over (partition by col1) as col4
from t;
您可以在 SELECT
中使用子查询来获取该值。
如果您介意一次又一次地执行它并交叉连接它,则可以将该 suq 查询存储在一个变量中。
架构 (PostgreSQL v10.0)
CREATE TABLE test (
"col 1" INTEGER,
"col 2" VARCHAR(3),
"col 3" INTEGER
);
INSERT INTO test
("col 1", "col 2", "col 3")
VALUES
('67458', 'ADM', '1008'),
('67458', 'ADM', '1009'),
('67458', 'SKI', '1009'),
('67458', 'LIS', '1010'),
('67458', 'TOU', '1121');
查询#1
SELECT MAX("col 3") AS "col 4" INTO col4 FROM test t2 WHERE t2."col 2" = 'ADM';
没有要显示的结果。
查询 #2
SELECT "col 1",
"col 2",
"col 3",
"col 4"
FROM test
CROSS JOIN
col4;
输出
| col 1 | col 2 | col 3 | col 4 |
| ----- | ----- | ----- | ----- |
| 67458 | ADM | 1008 | 1009 |
| 67458 | ADM | 1009 | 1009 |
| 67458 | SKI | 1009 | 1009 |
| 67458 | LIS | 1010 | 1009 |
| 67458 | TOU | 1121 | 1009 |
SELECT t.*, max(CASE WHEN col2 = 'ADM' THEN col3 END) OVER (PARTITION BY col1) AS col4
FROM tbl t;
聚合 FILTER
子句是在 PostgreSQL 9.4 中引入的,对此非常有用。但是 Redshift 不是 Postgres,Postgres 中后来添加的大部分内容在那里不受支持。比较:
- How can I simplify this game statistics query?