请注意,您的问题仍然有些模棱两可;当 J 的最大值超过一条记录时,应该返回什么。你会返回一条记录还是多条记录?我的回答仅适用于您希望返回一条记录的情况。
在这种情况下,下面的查询,对 i 使用 FIRST/LAST 聚合函数,是最有效的查询。
用你的桌子做一个小测试:
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)
问候,
罗布。