id
、year
、およびcount
を含むテーブルがあります。
各id
のMAX(count)
を取得し、発生したときに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
´s MAX(count)
とそれが発生する年を取得したい。
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
最短の(おそらく最速の)クエリは、SQL標準DISTINCT
のPostgreSQL拡張である DISTINCT ON
を使用します。句:
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
の順に並べられますが、歓迎されない場合もあります。いずれの場合も「未定義」よりも優れています。
また、明確に定義された方法で(複数の年が同じ最大数を共有する場合)関係を壊します:最も早い年を選択します。気にしない場合は、ORDER BY
からyear
を削除します。または、year DESC
で最新の年を選択します。
この密接に関連する答えの詳細な説明、リンク、ベンチマーク、およびおそらくより高速なソリューション:
余談:実際のクエリでは、列名の一部を使用しません。 id
は列名の非記述的なアンチパターンで、count
は 標準SQLの予約語 およびPostgresの集約関数です。