11

私のテーブル:

ID   NUM   VAL
1    1     Hello
1    2     Goodbye
2    2     Hey
2    4     What's up?
3    5     See you

各 ID の最大数を返したい場合は、非常に適切でクリーンです。

SELECT MAX(NUM) FROM table GROUP BY (ID)

しかし、各 ID の各数値の最大値に関連付けられた値を取得したい場合はどうすればよいでしょうか?

できない理由:

SELECT MAX(NUM) OVER (ORDER BY NUM) FROM table GROUP BY (ID) 

なぜそれはエラーですか?ウィンドウごとに個別にパーティション分割するのではなく、この選択をIDでグループ化したいと思います...

編集: エラーは「GROUP BY 式ではありません」です。

4

3 に答える 3

16

おそらく次のMAX() KEEP(DENSE_RANK LAST...)関数を使用できます。

with sample_data as (
  select 1 id, 1 num, 'Hello' val from dual union all
  select 1 id, 2 num, 'Goodbye' val from dual union all
  select 2 id, 2 num, 'Hey' val from dual union all
  select 2 id, 4 num, 'What''s up?' val from dual union all
  select 3 id, 5 num, 'See you' val from dual)
select id, max(num), max(val) keep (dense_rank last order by num)
from sample_data
group by id;
于 2012-04-27T23:20:45.277 に答える
4

ウィンドウ関数を使用する場合、もう GROUP BY を使用する必要はありません。これで十分です。

select id, 
     max(num) over(partition by id) 
from x 

実際には、ウィンドウ関数を使用せずに結果を取得できます。

select * 
from x
where (id,num) in
  (
     select id, max(num) 
     from x 
     group by id
  )

出力:

ID  NUM VAL
1   2   Goodbye
2   4   What's up
3   5   SEE YOU

http://www.sqlfiddle.com/#!4/a9a07/7


ウィンドウ関数を使用する場合は、次のようにします。

select id, val, 
     case when num =  max(num) over(partition by id) then
        1
     else
        0
     end as to_select
from x 
where to_select = 1

またはこれ:

select id, val 
from x 
where num =  max(num) over(partition by id) 

しかし、それらを行うことは許可されていないため、次のことを行う必要があります。

with list as
(
  select id, val, 
     case when num =  max(num) over(partition by id) then
        1
     else
        0
     end as to_select
  from x
)
select * 
from list 
where to_select = 1

http://www.sqlfiddle.com/#!4/a9a07/19

于 2012-04-27T23:33:17.217 に答える
3

からの値を含むを取得しようとしている場合MAX(num) GROUP BY id、これは一般的なパターンになる傾向があります...

WITH
  sequenced_data
AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY id ORDER BY num DESC) AS sequence_id,
    *
  FROM
    yourTable
)
SELECT
  *
FROM
  sequenced_data
WHERE
  sequence_id = 1


編集

TeraDataがこれを許可するかどうかはわかりませんが、ロジックは理にかなっているようです...

SELECT
  *
FROM
  yourTable
WHERE
  num = MAX(num) OVER (PARTITION BY id)

または多分...

SELECT
  *
FROM
(
  SELECT
    *,
    MAX(num) OVER (PARTITION BY id) AS max_num_by_id
  FROM
    yourTable
)
  AS sub_query
WHERE
  num = max_num_by_id 

これは私の以前の回答とは少し異なります。複数のレコードが同じMAX(num).


編集

提案された SQL では、エラーはOVER()句に GROUP BY にないフィールドが含まれているという事実に関連しています。これをしようとしているようです...

SELECT id, num FROM yourTable GROUP BY id

num返される行ごとにそのフィールドに複数の値が存在する可能性があるため、無効です(返される行は によって定義されますGROUP BY id)

同様に、句numの中に入れることはできません。OVER()

SELECT

  id,

  MAX(num),                <-- Valid as it is an aggregate

  MAX(num)                 <-- still valid
  OVER(PARTITION BY id),   <-- Also valid, as id is in the GROUP BY

  MAX(num)                 <-- still valid
  OVER(PARTITION BY num)   <-- Not valid, as num is not in the GROUP BY

FROM
  yourTable
GROUP BY
  id


OVER()句で何かを指定できない場合については、この質問を参照してください

于 2012-04-27T23:23:53.977 に答える