web-dev-qa-db-ja.com

Postgres:明確だが1列のみ

Pgsqlに名前(1行以上の行)を持つテーブルがありますが、重複も多くあります。 idnamemetadataの3つのフィールドを選択します。

ORDER BY RANDOM()LIMIT 1000でランダムに選択したいので、PHPスクリプトのメモリを節約するために多くの手順を実行します。

しかし、どうすれば名前に重複がないリストのみが表示されるのでしょうか。

たとえば、[1,"Michael Fox","2003-03-03,34,M,4545"]は返されますが、[2,"Michael Fox","1989-02-23,M,5633"]は返されません。名前フィールドは最も重要であり、選択するたびにリスト内で一意でなければならず、ランダムでなければなりません。

GROUP BY nameで試しましたが、GROUP BYまたはaggragate関数にidとメタデータがあることを期待していますが、何らかの方法でフィルターにかけたくありません。

多くの列をフェッチする方法を知っている人はいますが、1つの列でのみ区別しますか?

102
NovumCoder

1つ(またはn)の列のみを区別するには:

select distinct on (name)
    name, col1, col2
from names

これにより、名前を含むすべての行が返されます。返される行を制御する場合は、注文する必要があります。

select distinct on (name)
    name, col1, col2
from names
order by name, col1

Col1で並べ替えると、最初の行を返します。

distinct on

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

DISTINCT ON式は、左端のORDER BY式と一致する必要があります。通常、ORDER BY句には、各DISTINCT ONグループ内の行の優先順位を決定する追加の式が含まれます。

189
Clodoaldo Neto

多くの列をフェッチする方法を知っている人はいますが、1つの列でのみ区別しますか?

DISTINCT ON が必要です。

サンプルデータまたは完全なクエリを提供しなかったため、表示できるものはありません。次のようなものを書きたい:

SELECT DISTINCT ON (name) fields, id, name, metadata FROM the_table;

これにより、予測不可能な(「ランダム」ではない)行のセットが返されます。予測可能にしたい場合は、クロダルドの答えごとにORDER BYを追加してください。本当にランダムにしたい場合は、ORDER BY random()にする必要があります。

16
Craig Ringer
SELECT NAME,MAX(ID) as ID,MAX(METADATA) as METADATA 
from SOMETABLE
GROUP BY NAME
4
David Jashi