ど素人から毛を生やす。<延>

ダブランとTRPGを愛する、社会不適合者ぎりぎりのweb会社員が、
仕事の技術碌を書き連ねたり夢を叶えようとしたり趣味にいそしんだりする場末のブログ。

HN 餅。
好きなポケモン ダブラン / バタフリー / ピンクの悪魔ラッキー / ナマコブシ / ワタッコはいいぞ。
最近ポケモンスリープを始めた

[MySQL]GROUPしたテーブルのOR検索、AND検索、NOT検索

Web > Other 2026年1月7日

どもです。割と多用するのに忘れがちなので備忘録。
結論から言うと “ HAVING COUNT(条件 OR NULL) ” または 相関サブクエリと“ EXISTS ”系関数 を用いる。

例えばこういったテーブルで。

tableA
idvalue
A1
A2
A3
B1
B2
SELECT * FROM tableA AS A GROUP BY A.id

valueをそれぞれOR検索、AND検索、NOT検索して結果を取り出したい場合は?

OR検索

これは単純に実現できる。

WHERE value IN (1,2)

でもSELECTの結果に検索対象外カラムの情報が欲しい場合は、ANDやNOTと同様にHAVINGを使う。

HAVING COUNT(value IN (1,2) OR NULL) > 0

または、相関サブクエリとEXISTSを用いる。

WHERE EXISTS ( SELECT 1 FROM tableA AS AA WHERE AA.id = A.id AND AA.value IN (1,2) )

速度は [単純にWHERE](5) > [HAVING](7) くらい差がある。
[EXISTS] は対象データの状態に大きく左右されて、(1~10)くらいバラついた。

AND検索

WHEREでなくHAVINGを使う。※COUNT(X OR NULL)は条件を満たす場合のみ計上する

HAVING COUNT(value IN (1,2) OR NULL) = 2

または、相関サブクエリを使う。

WHERE ( SELECT COUNT(DISTINCT value) FROM tableA AS AA WHERE AA.id = A.id AND AA.value IN (1,2) ) = 2

速度は [相関サブクエリ](6) > [HAVING](7) 。サブクエリの方が微早。

NOT検索

WHEREでなくHAVINGを使う。

HAVING COUNT(value IN (1,2) OR NULL) = 0

または、相関サブクエリとNOT EXISTSを用いる。

WHERE NOT EXISTS ( SELECT 1 FROM tableA AS AA WHERE AA.id = A.id AND AA.value IN (1,2) )

速度は [NOT EXISTS](1~5) > [HAVING](7) 。
NOT EXISTS の速度も EXISTS 同様、検索対象の状態に大きく依存したが、計測した限りでは最大速度が EXISTS より速い結果になった。


値が動的になったりJOINしてSQLが複雑化したりても、基本形や特徴は同じ。
インデックスが正しく貼れていれば、基本的には相関サブクエリ使用の方がやや早い。ただし検索内容によって結果が早くも遅くもブレるので、自分はHAVINGの方が好き。

この記事は役に立ちましたか?
  • _(:3」∠)_ 面白かった (0)
  • (・∀・) 参考になった (0)
  • (`・ω・´) 役に立った (0)