0

我有 testmax 表如下:

I                      J                      
---------------------- ---------------------- 
1                      2                      
2                      4                      
3                      3       

现在,问题是我怎样才能找到具有最大 J 的 I,通过以下我只能找到最大 J

SELECT MAX(j) 
  FROM testmax

但通过以下我得到这个错误:ORA-00937: not a single-group group function:

SELECT i, MAX(j) 
  FROM testmax
4

5 回答 5

4

请注意,您的问题仍然有些模棱两可;当 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)

问候,
罗布。

于 2011-06-04T19:10:39.150 回答
3
SELECT i, j
  FROM testmax
 WHERE j = ( SELECT MAX(j) from testmax )

如果 j 不是唯一的,这可能会返回多于一行。

于 2011-06-03T23:39:59.410 回答
1

我想你可以先简化一下查询,然后我们就可以用它order by来清理了。

SELECT year, COUNT(*) AS c
FROM 
Movie M INNER JOIN ActedIn A ON M.movieID=A.MovieID
WHERE A.actorID=518238628
GROUP BY year
ORDER BY COUNT(*) DESC LIMIT 1;

您的 RDBMS 可能会SELECT TOP 1使用LIMIT 1.

于 2011-06-03T23:26:36.020 回答
1

这可能比使用子查询更有效。

select i,j
  from (
    select i, j, max(j) over () max_j
      from testmax
  )
  where j=max_j
  ;
于 2011-06-04T13:35:34.773 回答
0

having需要查询聚合函数时使用子句更正确

select i, max(j)
  from testmax
 group by i
having max(j) = (select max(j) from testmax);

I                      MAX(J)                 
---------------------- ---------------------- 
2                      4                      

1 rows selected
于 2011-06-06T09:11:15.087 回答