64

、、のテーブルがidありyearますcount

MAX(count)それぞれのを取得し、それが発生したときにid保持したいので、次のクエリを実行します。year

SELECT id, year, MAX(count)
FROM table
GROUP BY id;

残念ながら、エラーが発生します。

エラー:列 "table.year"は、GROUP BY句に含めるか、集計関数で使用する必要があります

だから私は試してみます:

SELECT id, year, MAX(count)
FROM table
GROUP BY id, year;

しかし、それはしませんMAX(count)、それはそのままテーブルを表示するだけです。とでグループ化するyearと、その特定の年idの最大値が得られるためだと思います。id

では、どうすればそのクエリを書くことができますか?id私はそれがMAX(count)起こる年とを取得したいと思います。

4

2 に答える 2

90

最短の (そしておそらく最速の) クエリは、SQL 標準句DISTINCT ONの PostgreSQL 拡張である を使用したものです。DISTINCT

SELECT DISTINCT ON (1)
       id, count, year
FROM   tbl
ORDER  BY 1, 2 DESC, 3;

番号は、リスト内の序数を示しSELECTます。わかりやすくするために、列名を綴ることができます。

SELECT DISTINCT ON (id)
       id, count, year
FROM   tbl
ORDER  BY id, count DESC, year;

id結果は、歓迎される場合もあれば、歓迎されない場合もある etc.によって順序付けられます。いずれにせよ、「未定義」よりはましです。

また、(複数の年が同じ最大数を共有している場合) 明確に定義された方法で引き分けます: 最も早い年を選択します。気にしない場合は、 からドロップyearしてORDER BYください。または で最新の年を選択しyear DESCます。

あたりの行数が多い場合id、他のクエリ手法の方が (はるかに) 高速です。見る:

于 2012-11-11T02:08:43.147 に答える
59
select *
from (
  select id, 
         year,
         thing,
         max(thing) over (partition by id) as max_thing
  from the_table
) t
where thing = max_thing

また:

select t1.id,
       t1.year,
       t1.thing
from the_table t1
where t1.thing = (select max(t2.thing) 
                  from the_table t2
                  where t2.id = t1.id);

また

select t1.id,
       t1.year,
       t1.thing
from the_table t1
  join ( 
    select id, max(t2.thing) as max_thing
    from the_table t2
    group by id
  ) t on t.id = t1.id and t.max_thing = t1.thing

または(前と同じで表記が異なる)

with max_stuff as (
  select id, max(t2.thing) as max_thing
  from the_table t2
  group by id
) 
select t1.id, 
       t1.year,
       t1.thing
from the_table t1
  join max_stuff t2 
    on t1.id = t2.id 
   and t1.thing = t2.max_thing
于 2012-11-10T20:15:16.103 に答える