テーブルが与えられた場合、グループ内に[a, b, c, d]
ある行を正確に選択したいと思います。max(a)
c
つまり、a
=の行select max(a) from table group by c
これを行うための最も効率的な方法は何ですか?パーティション句などは使えますか?
現実の世界では、ほとんどの場合、問題の特殊性である手がかりが存在し、自分に都合がよいと推測できます。
あなたの問題は理想的なケースですが、特殊性はありません。このクエリは、テーブルを完全にスキャンし、いくつかの並べ替えを行って最大値を見つけます。
select a,b,c,d
from(
select
a,
b,
c,
d,
row_number() over (partition by c order by a desc) as rnk_in_group_of_c
from table
)
where rnk_in_group_of_c = 1;
このクエリは、サブクエリを使用して最大値を見つけるよりも優れています。これは、複数のフル スキャン、不要なネストされたループ、またはその他のパフォーマンスの問題が発生する可能性があるためです。
最大aを持つすべての行が必要な場合(つまり、2つの等しい最大行がある場合)、dense_rank()
代わりに関数を使用する必要があることに注意してくださいrow_number()
これを試してみましたか?keep (dense_rank first
これは私を大いに助け、パフォーマンスはずっと良くなる可能性があります。
select
max(a) a,
max(b) keep (dense_rank first order by a desc) b,
c,
max(d) keep (dense_rank first order by a desc) d
from table
group by c
オプションのorderbyは、パーティションの後に追加できます。
SELECT max(a) OVER (PARTITION BY c) max_c FROM...