Самый эффективный способ получить запись от MAX (col2), сгруппированных по col1 - PullRequest
0 голосов
/ 27 марта 2019

У меня есть таблица, такая как ниже:

|col1|col2|col3|col4|col5|
|----|----|----|----|----|
|A   |1   |x   |y   |y   |
|A   |2   |x   |x   |y   |
|B   |1   |x   |y   |x   |

Что я хочу сделать, так это вернуть одну запись для неуникального значения в столбце col1 на основе максимального значения в столбце col2.

Я мог бы сделать это с помощью внутреннего соединения, такого как:

SELECT a.*
  FROM table a INNER JOIN (
                   SELECT col1, 
                          MAX(col2)
                     FROM table
                 GROUP BY col1) b 
       ON b.col1 = a.col1 AND b.col2 = a.col2

Что бы вернуть:

|col1|col2|col3|col4|col5|
|----|----|----|----|----|
|A   |2   |x   |x   |y   |
|B   |1   |x   |y   |x   |

Однако это кажется неэффективным. Есть ли более эффективный способ сделать это?

Ответы [ 3 ]

1 голос
/ 27 марта 2019

использовать коррелированный подзапрос

select * from tablename a
where col2 in (select max(col2) from tablename b where a.col1=b.col1)
1 голос
/ 27 марта 2019

Вы используете Oracle, для этого простого случая не нужно использовать коррелированные подзапросы или самостоятельные объединения. Просто используйте аналитические функции.

with s (col1, col2, col3, col4, col5) as (
select 'A', 1, 'x', 'y', 'y' from dual union all
select 'A', 2, 'x', 'x', 'y' from dual union all
select 'B', 1, 'x', 'y', 'x' from dual)
select*
from
 (select s.*, max(col2) over (partition by col1) mx
  from s
 )
where col2 = mx;

C       COL2 C C C         MX
- ---------- - - - ----------
A          2 x x y          2
B          1 x y x          1

Elapsed: 00:00:00.00

with s (col1, col2, col3, col4, col5) as (
select 'A', 1, 'x', 'y', 'y' from dual union all
select 'A', 2, 'x', 'x', 'y' from dual union all
select 'B', 1, 'x', 'y', 'x' from dual)
select*
from
 (select s.*, row_number() over (partition by col1 order by col2 desc) rn
  from s
 )
where rn = 1;

C       COL2 C C C         RN
- ---------- - - - ----------
A          2 x x y          1
B          1 x y x          1

Elapsed: 00:00:00.00

with s (col1, col2, col3, col4, col5) as (
select 'A', 1, 'x', 'y', 'y' from dual union all
select 'A', 2, 'x', 'x', 'y' from dual union all
select 'B', 1, 'x', 'y', 'x' from dual)
select
col1,
max(col2) col2,
max(col3) keep (dense_rank last order by col2) col3,
max(col4) keep (dense_rank last order by col2) col4,
max(col5) keep (dense_rank last order by col2) col5
from s
group by col1;

C       COL2 C C C
- ---------- - - -
A          2 x x y
B          1 x y x

Elapsed: 00:00:00.01
1 голос
/ 27 марта 2019

Я думаю, вы можете предпочесть использовать оператор in с более прямым способом

select *
  from "table"
 where (col1,col2) in ( select col1,max(col2)
                          from "table"
                         group by col1 
                          )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...