は、GROUP BY句に記述するか、集約関数で使用する必要があります。
このようなテーブルがあります;
cname | wmname | avg
--------+-------------+------------------------
canada | zoro | 2.0000000000000000
spain | luffy | 1.00000000000000000000
spain | usopp | 5.0000000000000000
それぞれのcnameの最大平均値を選択したい。
SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname;
を選択したいのですが、エラーが発生します、
ERROR: column "makerar.wmname" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname;
そこで、次のようにしました。
SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname, wmname;
しかし、これでは意図した結果が得られず、以下のような誤った出力が表示されます。
cname | wmname | max
--------+--------+------------------------
canada | zoro | 2.0000000000000000
spain | luffy | 1.00000000000000000000
spain | usopp | 5.0000000000000000
実際の結果は
cname | wmname | max
--------+--------+------------------------
canada | zoro | 2.0000000000000000
spain | usopp | 5.0000000000000000
この問題を解決するにはどうすればよいですか?
注:このテーブルは以前の操作で作成されたVIEWです。
239
7
はい、これは一般的な集約の問題です。SQL3 (1999)]1以前では、選択されたフィールドは
GROUP BY
句*に記述しなければなりませんでした。この問題を回避するためには、サブクエリで集計を計算し、表示する必要がある追加列を得るためにそれ自身と結合する必要があります:
しかし、ウィンドウ関数を使うこともできる:
この方法の唯一の点は、すべてのレコードを表示するということです(ウィンドウ関数はグループ化しません)。しかし、各行の国の正しい(つまり
cname
レベルで最大の)MAX
を表示するので、あなた次第である:MAX値に一致する
(cname, wmname)
タプルのみを表示する、あまりエレガントとは言えないかもしれませんが、次のような解決策もあります:Postgresでは、特別な
DISTINCT ON (expression)
構文を使用することもできます:「group by」選択でグループ化されていないフィールドと非集計フィールドを指定する際の問題は、この場合、エンジンはどのレコードのフィールドを返す必要があるかを知る方法がないことです。 最初ですか? 最後ですか? 通常、集計結果に自然に対応するレコードはありません(「min」と「max」は例外です)。
ただし、回避策があります。必要なフィールドも集計します。 雑踏では、これはうまくいくはずです:
これにより、avgで順序付けられたすべてのwnamesの配列が作成され、最初の要素が返されることに注意してください(postgresの配列は1ベースです)。
rank()`ウィンドウ関数を使用しています:
**注意
どちらを用いても、グループごとに複数の最大値が保持されます。avgがmaxに等しいレコードが複数あっても、グループごとに1つのレコードだけが欲しい場合は、@ypercube'さんの回答を参照してください。
私にとって、それは「一般的な集約の問題」ではなく、誤ったSQLクエリについてです。 「各cnameの最大平均を選択します。..」です。
結果は次のとおりです。
この結果は、一般的に次の質問に答えます「各グループに最適な結果は何ですか?"。 スペインにとって最良の結果は5であり、カナダにとって最良の結果は2であることがわかります。 それは本当であり、エラーはありません。 wmname も表示する必要がある場合は、次の質問に答える必要があります。「結果のセットからwmnameを選択する RULE とは何ですか?「間違いを明確にするために、入力データを少し変更しましょう。
このクエリを実行すると、どの結果が期待されますか:
SELECT cname、wmname、MAX(avg)FROM makerar GROUP BY cname;
? 「spain + luffy」または「spain + usopp」である必要があります? なぜ? クエリで「より良い」 wmname を選択する方法が決定されていないので、いくつかが適切である場合、結果も決定されません。 これが、SQLインタープリターがエラーを返す理由です-クエリは正しくありません。言い換えれば、質問への正しい答えはありません「「スペイン」グループで誰が最高か?"。 usoppは同じ「スコア」を持っているので、Luffyはusoppに勝るものはありません。
最近、「case when」を使用してカウントしようとしたときにこの問題に遭遇し、「which」および「count」ステートメントの順序を変更すると問題が解決することがわかりました。
使用する代わりに-後者では、リンゴとオレンジが集約関数に表示されるというエラーが発生しました。
これもうまくいくようです。