web-dev-qa-db-ja.com

PostgreSQL:ソート順に基づいてIDごとに最初のレコードのみを選択します

次のクエリでは、shape_typeの値が最も小さい(1から10の範囲)最初のレコードのみを選択する必要があります。これを簡単に行う方法についての知識がpostgresqlである場合は、助けてください。御時間ありがとうございます。

select g.geo_id, gs.shape_type
from schema.geo g   
join schema.geo_shape gs on (g.geo_id=gs.geo_id)  
order by gs.shape_type asc;
14
Sarah Bergquist

PostgreSQLには、このタイプのクエリに対して非常に優れた構文があります distinct on

SELECT DISTINCT ON(式[、...])は、指定された式が等しいと評価される行の各セットの最初の行のみを保持します。 DISTINCT ON式は、ORDER BYの場合と同じルールを使用して解釈されます(上記を参照)。 ORDER BYを使用して目的の行が最初に表示されるようにしない限り、各セットの「最初の行」は予測できないことに注意してください。

したがって、クエリは次のようになります。

select distinct on(g.geo_id)
    g.geo_id, gs.shape_type
from schema.geo g   
    join schema.geo_shape gs on (g.geo_id=gs.geo_id)  
order by g.geo_id, gs.shape_type asc;

一般に、このためのANSI-SQL構文(ウィンドウ関数と共通テーブル式を備えたRDBMSで、サブクエリに切り替えることができます)は次のようになります。

with cte as (
    select
        row_number() over(partition by g.geo_id order by gs.shape_type) as rn,
        g.geo_id, gs.shape_type
    from schema.geo g   
        join schema.geo_shape gs on (g.geo_id=gs.geo_id)  
)
select
    geo_id, shape_type
from cte
where rn = 1
27
Roman Pekar