0

私は次のようなtestmaxテーブルを持っています:

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

さて、問題は、最大Jを持つIをどのように見つけることができるかということです。

SELECT MAX(j) 
  FROM testmax

しかし、次のようにすると、このエラーが発生します。ORA-00937: not a single-group group function:

SELECT i, MAX(j) 
  FROM testmax
4

5 に答える 5

4

あなたの質問はまだやや曖昧であることに注意してください。Jの最大値を持つレコードが複数ある場合、何を返す必要がありますか。1つのレコードを返すのですか、それとも複数のレコードを返すのですか。私の答えは、1つのレコードを返したい場合にのみ当てはまります。

その場合、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)

また、1つのテーブルスキャンを使用しますが、すべての行で分析関数を使用します。この場合、単一の集計で問題なく動作します。

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)

これは、1つではなく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 に答える