MySQLのGROUP BY句はどのようにDISTINCT句と同じように動作するのか?
GROUP BY句がDISTINCT句のように動作する仕組み
MySQLのSELECT文において、GROUP BY句を集計関数(SUM、COUNTなど)なしで使用した場合、その動作はDISTINCT句と同じになります。つまり、指定したカラムの重複した値が取り除かれ、一意な値だけが返されます。
ここでは、次のようなテーブル「testing」を使って、その挙動を確認してみましょう。
mysql> Select * from testing; +------+---------+---------+ | id | fname | Lname | +------+---------+---------+ | 200 | Raman | Kumar | | 201 | Sahil | Bhalla | | 202 | Gaurav | NULL | | 203 | Aarav | NULL | | 204 | Harshit | Khurana | | 205 | Rahul | NULL | | 206 | Piyush | Kohli | | 207 | Lovkesh | NULL | | 208 | Gaurav | Kumar | | 209 | Raman | Kumar | +------+---------+---------+ 10 rows in set (0.00 sec)
DISTINCT句を使用した場合
まず、「Lname」カラムに対してDISTINCT句を使用すると、MySQLは以下の結果セットを返します。
mysql> select Distinct LNAME from testing; +---------+ | LNAME | +---------+ | Kumar | | Bhalla | | NULL | | Khurana | | Kohli | +---------+ 5 rows in set (0.00 sec)
GROUP BY句を使用した場合
続いて、同じカラムにGROUP BY句を使用してみます。すると、DISTINCT句を使った場合と本質的に同じ結果セットが得られます。
mysql> Select LNAME from testing GROUP BY Lname; +---------+ | LNAME | +---------+ | NULL | | Bhalla | | Khurana | | Kohli | | Kumar | +---------+ 5 rows in set (0.04 sec)
両者の違い:結果の並び順
両方のクエリの結果セットを比較すると、一つ重要な違いがあることに気づきます。それは並び順(ソート順)です。
- GROUP BY句を使用した場合:結果セットはソートされた状態で返されます。
- DISTINCT句を使用した場合:結果セットはソートされず、内部的な処理順序のまま返されます。
このように、GROUP BY句を集計関数なしで使えばDISTINCT句の代わりとして機能しますが、GROUP BY句は暗黙的にソートを行う点で異なります。ただし、大量のデータを扱う場合はソートのコストが発生するため、単純に重複を除去したいだけであればDISTINCT句の方が効率的です。また、MySQL 8.0以降ではGROUP BYの暗黙的なソートは保証されなくなっているため、確定的な順序が必要な場合はORDER BY句を明示的に指定することをおすすめします。
-
MySQLでグループごとにランダムな順序で並べ替える方法
MySQLでデータを取得する際、「同じ値を持つレコード同士はまとめたいが、グループ全体の並び順は毎回ランダムにしたい」という要件が出てくることがあります。単純に ORDER BY RAND() を使うと行単位でバラバラになってしまうため、サブクエリとJOINを組み合わせるのがポイントです。この記事では、その具体的な手順をサンプルコード付きで解説します。 1. サンプルテーブルを作成する まず、動作確認用のテーブルを作成しましょう。 mysql> create table DemoTable ( Id int NOT NULL AUTO_
-
MySQLのGROUP BY句で各グループから1行だけを選択・抽出する方法
MySQLでは、GROUP BY句とサブクエリを組み合わせることで、各グループから特定の1行(たとえば最小のIDを持つ行)を取り出すことができます。本記事では、学生の点数データを例に、テーブル作成から実際のクエリ実行までの手順をわかりやすく解説します。 1. テーブルの作成 まず、以下のCREATE TABLE文でサンプル用のテーブルを作成します。 mysql> create table DemoTable1572 -> ( -> StudentId int, &nb