Обратите внимание, что ваш вопрос все еще несколько двусмысленен;что должно быть возвращено, если существует более одной записи с максимальным значением для J. Вернете ли вы одну запись или несколько?Мой ответ применим только в том случае, если вы хотите, чтобы одна запись была возвращена.
И в этом случае приведенный ниже запрос, использующий агрегатную функцию FIRST / LAST для i, является наиболее эффективным запросом.протестируйте с вашей таблицей:
SQL> create table testmax (i,j)
2 as
3 select 1, 2 from dual union all
4 select 2, 4 from dual union all
5 select 3, 3 from dual
6 /
Table created.
И запрос с использованием агрегатной функции LAST (http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/functions076.htm#sthref1540):
SQL> set autotrace on explain
SQL> select max(i) keep (dense_rank last order by j) i
2 , max(j)
3 from testmax
4 /
I MAX(J)
---------- ----------
2 4
1 row selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 44308443
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 26 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 26 | | |
| 2 | TABLE ACCESS FULL| TESTMAX | 3 | 78 | 3 (0)| 00:00:01 |
------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)
Также с одним сканированием таблицы, но с использованием аналитической функции для всех строк, гдес одним агрегатом все будет в порядке:
SQL> select i,j
2 from (
3 select i, j, max(j) over () max_j
4 from testmax
5 )
6 where j=max_j
7 /
I J
---------- ----------
2 4
1 row selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 1897951616
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 117 | 3 (0)| 00:00:01 |
|* 1 | VIEW | | 3 | 117 | 3 (0)| 00:00:01 |
| 2 | WINDOW BUFFER | | 3 | 78 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| TESTMAX | 3 | 78 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("J"="MAX_J")
Note
-----
- dynamic sampling used for this statement (level=2)
Этот использует два сканирования таблицы вместо одного:
SQL> SELECT i, j
2 FROM testmax
3 WHERE j = ( SELECT MAX(j) from testmax )
4 /
I J
---------- ----------
2 4
1 row selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3795151209
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 26 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL | TESTMAX | 1 | 26 | 3 (0)| 00:00:01 |
| 2 | SORT AGGREGATE | | 1 | 13 | | |
| 3 | TABLE ACCESS FULL| TESTMAX | 3 | 39 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("J"= (SELECT MAX("J") FROM "TESTMAX" "TESTMAX"))
Note
-----
- dynamic sampling used for this statement (level=2)
С уважением,
Роб.