55737


下記結果を返すSQLがある時

[code]

    SELECT id FROM (SELECT * FROM `s` WHERE `c_id` != 9) AS a
    1
    2
    5
    7
    
[/code]

「上記結果何れにも該当しない」という条件を指定するにはどうすれば良いですか？

* * *

やりたいことのイメージ

[code]

    SELECT * FROM `r` WHERE `t_id` != 1 かつ
    SELECT * FROM `r` WHERE `t_id` != 2 かつ
    SELECT * FROM `r` WHERE `t_id` != 5 かつ
    SELECT * FROM `r` WHERE `t_id` != 7
    
[/code]

そのまま書くと下記エラーとなります

[code]

    SELECT * FROM `r` WHERE `t_id` != (SELECT id FROM (SELECT * FROM `s` WHERE `c_id` != 9) AS a)
    #1242 - サブクエリが2行以上の結果を返します。
    
[/code]


CC BY-SA 4.0
2019-06-13T00:46:02.187
55734
2019-06-13T02:14:57.267
7886
question
mysql
SQLでループ。「サブクエリが2行以上の結果を返す場合の処理」について


問題のSQLから最小の変更で修正するなら、`NOT IN`句を利用してください。

[code]

    SELECT * FROM `r` WHERE `t_id` not in (SELECT id FROM (SELECT * FROM `s` WHERE `c_id` != 9) AS a)
    
[/code]


CC BY-SA 4.0
2019-06-13T01:31:06.073
55735
2019-06-13T01:31:06.073
2238
55734
answer


@htb さんの回答で問題なく解決済みですが、SQL初心者にありがちな質問なので別解で補足回答いたします。

複数行レコードが返ってくるサブクエリ(副問い合わせ)に対して`=`や`!=`などで比較をすると、どのレコードと比較するべきか構文解析できないので質問に記載されているエラーが発生します。

複数行副問い合わせの「何れかに該当する/何れにも該当しない」操作を行うためには、`IN/EXISTS/ANY/ALL`という[`複数行比較演算子`](http://www.nc-
lab.sie.dendai.ac.jp/practice_db2015B/node59.html)を使用します。

下記のSQLは全て[同一の結果](http://sqlfiddle.com/#!9/c3e3a2/12)を返します。

[code]

    # EXISTS
    SELECT * FROM `r` WHERE not exists (SELECT 1 FROM `s` WHERE `c_id` != 9 AND `c_id` = `t_id`);
    # IN
    SELECT * FROM `r` WHERE `t_id` not in (SELECT `id` FROM `s` WHERE `c_id` != 9);
    # ALL
    SELECT * FROM `r` WHERE `t_id` != all (SELECT `id` FROM `s` WHERE `c_id` != 9);
    
[/code]

DB環境によっては大量のレコードが返る副問い合わせで`not
in`を使うと、副問い合わせのレコードを全件チェックしてものすごくパフォーマンスが落ちることがあります。  
古いOracleでは`not
exists`を使うと反例のレコードが存在すると分かった時点で副問い合わせを切り上げる実行計画を立てるので、パフォーマンスが下がりにくいです。

そのため私が後輩を指導する時には、`not in`を`not exists`で代用できる場合は後者を使うように指導しています。  
なお質問で提示されたSQLとテーブルは簡潔でレコード数が少ないので、どの方法でも体感的な差はないと思いますが。


CC BY-SA 4.0
2019-06-13T02:14:57.267
55737
2019-06-13T02:14:57.267
9820
55734
answer