web-dev-qa-db-ja.com

PostgreSQL SELECTステートメントの重複行を排除する

これは私のクエリです:

SELECT autor.entwickler,anwendung.name
  FROM autor 
  left join anwendung
    on anwendung.name = autor.anwendung;

 entwickler |    name     
------------+-------------
 Benutzer 1 | Anwendung 1
 Benutzer 2 | Anwendung 1
 Benutzer 2 | Anwendung 2
 Benutzer 1 | Anwendung 3
 Benutzer 1 | Anwendung 4
 Benutzer 2 | Anwendung 4
(6 rows)

フィールドnameの個別の値ごとに1行を保持し、次のように他の行を破棄します。

 entwickler |    name     
------------+-------------
 Benutzer 1 | Anwendung 1
 Benutzer 2 | Anwendung 2
 Benutzer 1 | Anwendung 3
 Benutzer 1 | Anwendung 4

MySQLでは、次のようにします。

SELECT autor.entwickler,anwendung.name
  FROM autor
  left join anwendung
    on anwendung.name = autor.anwendung
 GROUP BY anwendung.name;

しかし、PostgreSQLは私にこのエラーを与えます:

エラー:列 "autor.entwickler"はGROUP BY句に出現するか、集約関数で使用する必要があります1行目:SELECT autor.entwickler FROM autorが結合に残っています...

私はエラーを完全に理解し、mysqlの実装はpostgresの実装よりもSQLに準拠していないと想定しています。しかし、どうすれば望ましい結果を得ることができますか?

18
The Surrican

PostgreSQLは現在、あいまいな_GROUP BY_ステートメントを許可していません。結果は、テーブルがスキャンされる順序、使用されるプランなどに依存します。このように、標準ではAFAIKが機能するはずですが、一部のデータベース(MySQLバージョンなど) 5.7まで)SELECTリストにあるが_GROUP BY_にない要素に対して最初に見つかった値を選択するだけの緩いクエリを許可します。

PostgreSQLでは、この種のクエリには _DISTINCT ON_ を使用する必要があります。

あなたは次のようなものを書きたいです:

_SELECT DISTINCT ON (anwendung.name) anwendung.name, autor.entwickler
FROM author 
left join anwendung on anwendung.name = autor.anwendung;
_

(フォローアップコメントに基づいて修正された構文)

これはMySQL 5.7の_group by_のANY_VALUE(...)疑似関数に少し似ていますが、逆に、_distinct on_句の値は一意である必要があり、任意の値列を指定できませんが指定されていません。

_ORDER BY_がない限り、どの値が選択されるかについての保証はありません。通常、予測可能性のために_ORDER BY_が必要です。

min()またはmax()のような集計を使用すると機能することにも注意してください。これは真実ですが、_DISTINCT ON_やあいまいな_GROUP BY_を使用する場合とは異なり、信頼性が高く予測可能な結果が得られますが、並べ替えや集計を追加する必要があるため、パフォーマンスコストがかかります。序数データ型。

35
Craig Ringer