在特定列上连接具有最小值和最大值的行
Join rows with minimum and maximum value on a specific column
我有一个 table 看起来像这样:
COL ID_1 FOR A4
COL ID_2 FOR A4
COL ID_3 FOR A4
SELECT 'A1' ID_1, 'B1' ID_2, 10 NUM, 'X' ID_3 FROM DUAL UNION ALL
SELECT 'A1' ID_1, 'B2' ID_2, 20 NUM, 'Y' ID_3 FROM DUAL UNION ALL
SELECT 'A1' ID_1, 'B3' ID_2, 30 NUM, 'Z' ID_3 FROM DUAL UNION ALL
SELECT 'C1' ID_1, 'B1' ID_2, 1 NUM, 'Q' ID_3 FROM DUAL UNION ALL
SELECT 'C1' ID_1, 'B2' ID_2, 2 NUM, 'W' ID_3 FROM DUAL UNION ALL
SELECT 'C1' ID_1, 'B3' ID_2, 3 NUM, 'E' ID_3 FROM DUAL UNION ALL
SELECT 'C1' ID_1, 'B4' ID_2, 4 NUM, 'R' ID_3 FROM DUAL;
ID_1 ID_2 NUM ID_3
---- ---- ---- ----
A1 B1 10 X
A1 B2 20 Y
A1 B3 30 Z
C1 B1 1 Q
C1 B2 2 W
C1 B3 3 E
C1 B4 4 R
7 rows selected.
我想在 NUM 列 上连接具有 最小值 和 最大值 值的行。结果集按 ID_1 列分组。例如:
ID_1 ID_2 NUM ID_3
---- ---- ---- ----
A1 B1 10 X <-- A1: THIS MIN(NUM)
A1 B2 20 Y
A1 B3 30 Z <-- A1: THIS MAX(NUM)
C1 B1 1 Q <-- C1: THIS MIN(NUM)
C1 B2 2 W
C1 B3 3 E
C1 B4 4 R <-- C1: THIS MAX(NUM)
7 rows selected.
预期的结果集是
A1 B1 10 X B3 30 Z
C1 B1 1 Q B4 4 R
请告知如何达到预期的结果。
像这样:
with cte as (
select
id_1, id_2, num, id_3,
row_number() over (partition by id_1 order by num) as rn1,
row_number() over (partition by id_1 order by num desc) as rn2
from t
)
select
cte1.id_1,
cte1.id_2, cte1.num, cte1.id_3,
cte2.id_2, cte2.num, cte2.id_3
from cte cte1
join cte cte2 on cte1.id_1 = cte2.id_1 and cte2.rn2 = 1
where cte1.rn1 = 1
您可以在没有任何 self-joins 的情况下使用聚合函数 KEEP (DENSE_RANK [FIRST|LAST] ORDER BY ...)
:
SELECT id_1,
MIN(id_2) KEEP (DENSE_RANK FIRST ORDER BY num) AS min_id_2,
MIN(num) AS min_num,
MIN(id_3) KEEP (DENSE_RANK FIRST ORDER BY num, id_2) AS min_id_3,
MAX(id_2) KEEP (DENSE_RANK LAST ORDER BY num) AS max_id_2,
MAX(num) AS max_num,
MAX(id_3) KEEP (DENSE_RANK LAST ORDER BY num, id_2) AS max_id_3
FROM table_name
GROUP BY id_1;
其中,对于示例数据,输出:
ID_1
MIN_ID_2
MIN_NUM
MIN_ID_3
MAX_ID_2
MAX_NUM
MAX_ID_3
A1
B1
10
X
B3
30
Z
C1
B1
1
Q
B4
4
R
db<>fiddle here
我有一个 table 看起来像这样:
COL ID_1 FOR A4
COL ID_2 FOR A4
COL ID_3 FOR A4
SELECT 'A1' ID_1, 'B1' ID_2, 10 NUM, 'X' ID_3 FROM DUAL UNION ALL
SELECT 'A1' ID_1, 'B2' ID_2, 20 NUM, 'Y' ID_3 FROM DUAL UNION ALL
SELECT 'A1' ID_1, 'B3' ID_2, 30 NUM, 'Z' ID_3 FROM DUAL UNION ALL
SELECT 'C1' ID_1, 'B1' ID_2, 1 NUM, 'Q' ID_3 FROM DUAL UNION ALL
SELECT 'C1' ID_1, 'B2' ID_2, 2 NUM, 'W' ID_3 FROM DUAL UNION ALL
SELECT 'C1' ID_1, 'B3' ID_2, 3 NUM, 'E' ID_3 FROM DUAL UNION ALL
SELECT 'C1' ID_1, 'B4' ID_2, 4 NUM, 'R' ID_3 FROM DUAL;
ID_1 ID_2 NUM ID_3
---- ---- ---- ----
A1 B1 10 X
A1 B2 20 Y
A1 B3 30 Z
C1 B1 1 Q
C1 B2 2 W
C1 B3 3 E
C1 B4 4 R
7 rows selected.
我想在 NUM 列 上连接具有 最小值 和 最大值 值的行。结果集按 ID_1 列分组。例如:
ID_1 ID_2 NUM ID_3
---- ---- ---- ----
A1 B1 10 X <-- A1: THIS MIN(NUM)
A1 B2 20 Y
A1 B3 30 Z <-- A1: THIS MAX(NUM)
C1 B1 1 Q <-- C1: THIS MIN(NUM)
C1 B2 2 W
C1 B3 3 E
C1 B4 4 R <-- C1: THIS MAX(NUM)
7 rows selected.
预期的结果集是
A1 B1 10 X B3 30 Z
C1 B1 1 Q B4 4 R
请告知如何达到预期的结果。
像这样:
with cte as (
select
id_1, id_2, num, id_3,
row_number() over (partition by id_1 order by num) as rn1,
row_number() over (partition by id_1 order by num desc) as rn2
from t
)
select
cte1.id_1,
cte1.id_2, cte1.num, cte1.id_3,
cte2.id_2, cte2.num, cte2.id_3
from cte cte1
join cte cte2 on cte1.id_1 = cte2.id_1 and cte2.rn2 = 1
where cte1.rn1 = 1
您可以在没有任何 self-joins 的情况下使用聚合函数 KEEP (DENSE_RANK [FIRST|LAST] ORDER BY ...)
:
SELECT id_1,
MIN(id_2) KEEP (DENSE_RANK FIRST ORDER BY num) AS min_id_2,
MIN(num) AS min_num,
MIN(id_3) KEEP (DENSE_RANK FIRST ORDER BY num, id_2) AS min_id_3,
MAX(id_2) KEEP (DENSE_RANK LAST ORDER BY num) AS max_id_2,
MAX(num) AS max_num,
MAX(id_3) KEEP (DENSE_RANK LAST ORDER BY num, id_2) AS max_id_3
FROM table_name
GROUP BY id_1;
其中,对于示例数据,输出:
ID_1 MIN_ID_2 MIN_NUM MIN_ID_3 MAX_ID_2 MAX_NUM MAX_ID_3 A1 B1 10 X B3 30 Z C1 B1 1 Q B4 4 R
db<>fiddle here