15

植物テーブルがあるとしましょう:

id fruit
1  banana
2  apple
3  orange

私はこれらを行うことができます

SELECT * FROM plant ORDER BY id;
SELECT * FROM plant ORDER BY fruit DESC;

これは明らかなことを行います。

しかし、私はこれに噛まれました、これは何をしますか?

SELECT * FROM plant ORDER BY SUM(id);
SELECT * FROM plant ORDER BY COUNT(fruit);
SELECT * FROM plant ORDER BY COUNT(*);
SELECT * FROM plant ORDER BY SUM(1) DESC;

これらはすべて最初の行 (id = 1) のみを返します。

  1. アンダーフードで何が起こっているのですか?
  2. 集計関数が役立つシナリオは何ORDER BYですか?
4

3 に答える 3

24

テーブルから列ではなく集計値を実際に選択すると、結果がより明確になります。

SELECT SUM(id) FROM plant ORDER BY SUM(id)

これにより、すべての ID の合計が返されます。もちろん、これは役に立たない例です。なぜなら、集計では常に 1 つの行しか作成されないため、順序付けの必要がないからです。クエリで行qi番目の列を取得する理由は、MySQLがランダムではなく決定論的でもない1行を選択するためです。あなたの場合、それがテーブルの最初の列であることがたまたまありますが、ストレージエンジン、主キーなどによっては、他の列が別の行を取得する場合があります。したがって、ORDER BY 句のみでの集計はあまり役に立ちません。

通常、特定のフィールドでグループ化し、結果セットを何らかの方法で並べ替えます。

SELECT fruit, COUNT(*)
FROM plant
GROUP BY fruit
ORDER BY COUNT(*)

これはさらに興味深いクエリです。これにより、果物ごとに 1 つの行と、その果物の合計数が表示されます。さらにリンゴを追加してみると、実際に順序付けが意味をなすようになります。

完全な表:

+----+--------+
| id | fruit  |
+----+--------+
|  1 | banana |
|  2 | apple  |
|  3 | orange |
|  4 | apple  |
|  5 | apple  |
|  6 | banana |
+----+--------+

上記のクエリ:

+--------+----------+
| fruit  | COUNT(*) |
+--------+----------+
| orange |        1 |
| banana |        2 |
| apple  |        3 |
+--------+----------+
于 2012-10-27T10:28:21.073 に答える
4

これらのクエリはすべて、SQL 標準に準拠している SQL プラットフォームでは構文エラーになります。

SELECT * FROM plant ORDER BY SUM(id);
SELECT * FROM plant ORDER BY COUNT(fruit);
SELECT * FROM plant ORDER BY COUNT(*);
SELECT * FROM plant ORDER BY SUM(1) DESC;

たとえば、PostgreSQL では、これらすべてのクエリで同じエラーが発生します。

エラー: 列 "plant.id" は GROUP BY 句に指定するか、集計関数で使用する必要があります

これは、GROUP BY を使用せずにドメイン集計関数を使用していることを意味します。SQL Server と Oracle は同様のエラー メッセージを返します。

MySQL の GROUP BY は、少なくとも標準的な動作に関する限り、いくつかの点で壊れていることが知られています。しかし、あなたが投稿したクエリは、私にとって新しい壊れた動作だったので、+1.

内部で何をしているのかを理解しようとするよりも、標準的な GROUP BY クエリの書き方を学んだほうがよいでしょう。私の知る限り、MySQLは標準の GROUP BY ステートメントを正しく処理します。

以前のバージョンの MySQL ドキュメントでは、GROUP BY と非表示の列について警告されていました。(参考文献はありませんが、このテキストはあちこちで引用されています。)

GROUP BY 部分から除外する列がグループ内で一定でない場合は、この機能を使用しないでください。サーバーはグループから任意の値を自由に返すことができるため、すべての値が同じでない限り、結果は不確定です。

最近のバージョンは少し異なります。

この機能を使用すると、不要な列の並べ替えやグループ化を回避してパフォーマンスを向上させることができます。ただし、これは主に、GROUP BY で指定されていない各非集計列のすべての値が各グループで同じ場合に役立ちます。サーバーは各グループから任意の値を自由に選択できるため、それらが同じでない限り、選択された値は不確定です。

個人的には、SQL の機能が不確定であるとは考えていません。

于 2012-10-27T10:40:33.837 に答える
2
  1. そのような集計を使用すると、クエリは、結果全体が単一のグループになる暗黙的なグループを取得します。

  2. order by での集計の使用は、group by がある場合にのみ役立ちます。そのため、結果に複数の行が含まれる可能性があります。

于 2012-10-27T10:34:49.980 に答える