かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

MySQL 複数のコラムをGROUP BYして条件にしたレコードを取得したい

MySQL 5.7 以上でGROUP BYしてレコードをまるっと取ってくる方法は分かりました。 複数のカラムをGROUP BYして検索条件にしてレコードを取ってきたいと思います。

テーブル table_a

id name typeID
1 星宮いちご 1
2 霧矢あおい 2
3 紫吹蘭 3
4 神崎美月 3
5 星宮いちご 1

nametypeIDが重複しているデータのレコードを取得したい

重複しているデータの取得するのはONLY_FULL_GROUP_BY、つまりGROUP BYで使うカラムだけ表示するのは特に難しくありません。

SELECT typeID, name FROM table_a
GROUP BY typeID, name
HAVING COUNT(typeID) >= 2 AND COUNT(name) >= 2;

+--------+-----------------+
| typeID | name            |
+--------+-----------------+
|      1 | 星宮いちご        |
+--------+-----------------+

idカラムを含めたレコード全てのカラムを表示するには、GROUP BYで取得するデータをサブクエリにする必要があります。
今回GROUP BYしているクエリがtypeID, nameの2カラム返すのでWHEREの条件もtypeIDnameがマッチするようにしなければなりません。

WHEW (カラム名, カラム名, ...) in (値, 値, ... ) の形式にする

値が複数になる時は、マッチさせるカラム名側も()で囲い,区切りで指定すればOK

SELECT * FROM table_a
WHERE (typeID, name) IN (
  SELECT typeID, name FROM table_a
  GROUP BY typeID, name
  HAVING COUNT(typeID) >= 2 AND COUNT(name) >= 2
);

+----+-----------------+--------+
| id | name            | typeID |
+----+-----------------+--------+
|  1 | 星宮いちご      |      1 |
|  5 | 星宮いちご      |      1 |
+----+-----------------+--------+

WHEREのカラムが合ってないと...

SELECT * FROM table_a
WHERE typeID IN (
  SELECT typeID, name FROM table_a
  GROUP BY typeID, name
  HAVING COUNT(typeID) >= 2 AND COUNT(name) >= 2
);

Operand should contain 1 column(s) エラー

WHEREのカラム名()で囲ってないと...

SELECT * FROM table_a
WHERE typeID, name IN (
  SELECT typeID, name FROM table_a
  GROUP BY typeID, name
  HAVING COUNT(typeID) >= 2 AND COUNT(name) >= 2
);

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near... シンタックスエラーになります。

複数のGROUP BYを条件にしたSQLを書いたことがなかったのでチョットハマりました。 単純にWHEW 〜 IN 〜 で複数の条件を扱う方法を知っていればONLY_FULL_GROUP_BYオプションがONでも大した問題ではなかったですね…


[参考]

基礎からのMySQL 第3版 (基礎からシリーズ)

基礎からのMySQL 第3版 (基礎からシリーズ)