8

これは、2 つのテスト テーブルの sqlfiddle です: http://sqlfiddle.com/#!9/33361/3

tl;dr: SQL クエリに値!= 0が含まれないのはなぜですか?NULL

私は2つのテーブルをLEFT JOINしています。NULLintableB.field1または1inを持つ行を表示したいのですが、 inを持つ行tableB.field1はすべて除外します。0tableB.field1

このクエリ (例 6) でこの結果が得られると思いますが、null レコードは取得されません。

SELECT * FROM tableA a
LEFT JOIN tableB b ON a.id = b.join_id
WHERE
b.field1 != 0;

この長いクエリを使用する必要があります (例 4):

SELECT * FROM tableA a
LEFT JOIN tableB b ON a.id = b.join_id
WHERE
b.field1 != 0 OR b.field1 IS NULL;

何よりも興味深いのは、MySQL が NULL を != 0 と見なさないのはなぜですか?

条件を ON 句に移動すると、予期しない行が表示されます。

mysql> SELECT * FROM tableA a
    -> LEFT JOIN tableB b ON a.id = b.join_id AND b.field1 != 0;
+------+--------+--------+---------+--------+--------+
| id   | field1 | field2 | join_id | field1 | field2 |
+------+--------+--------+---------+--------+--------+
|    1 | testA1 | testA1 |       1 | 1      | testB1 |
|    2 | testA2 | testA2 |    NULL | NULL   | NULL   |
|    3 | testA3 | testA3 |    NULL | NULL   | NULL   |
+------+--------+--------+---------+--------+--------+
3 rows in set (0.00 sec)
4

3 に答える 3

8

!= 0 の SQL クエリに NULL 値が含まれないのはなぜですか?

簡単な答え:SELECT 0 != NULL返品するため(NULL)

より長い答え: MySQL のドキュメントによると

=、<、<> などの算術比較演算子を使用して NULL をテストすることはできません。

Select 句に NULL を含めたい場合は、「IS NULL」または「IFNULL」を使用して算術表現に変換する必要があります。

SQL クエリは次のように書き換えることができます。

SELECT * 
FROM tableA a
LEFT JOIN tableB b ON a.id = b.join_id
WHERE
    IFNULL(b.field1, -1) != 0;
于 2016-03-10T16:51:38.877 に答える
1

外部結合を使用する場合、SQL エンジンは、NULL 値を使用して結合セットにデータがないことを表します。null 値に対する等値チェックは常に false を返します。

考慮してください: null = null then 1 の場合、else 0 end これは常に 0 になります!

あなたは尋ねました: != 0 の SQL クエリに NULL 値が含まれないのはなぜですか?

クエリでは、エンジンが結合されたデータ セットを生成した後に where 句が適用されます。
A の ID は 1,2 で、B の ID は 1 のみであるとします。

左の結合からの結果セットには、where 句がありません。

  A.ID B.ID
    1  1
    2  NULL

where句が適用されます b.field !=0

そしてあなたは得る

  A.ID B.ID
    1  1

Null 等値チェックは常に FALSE と評価されるため、2 行目は除外され、1 行目は保持されます。

フィルターを結合条件に移動すると、テーブルが結合される前に制限が適用されます。

SELECT * FROM tableA a
LEFT JOIN tableB b 
   ON a.id = b.join_id
  and b.field1 != 0;

  A.ID B.ID
    1  1
    2  NULL

B には行 2 のレコードがないため、両方の行が取得されます。

MySQL が NULL を != 0 と見なさないのはなぜですか?

Null は特殊なケースです。null に対する等値比較では、常に false が返されます。

is nullは、is not null値が null かどうかを確認するために使用できる 2 つの方法です。

where coalesce(b.field1,1) != 02 番目のレコードが確実に返されるようにするためにも使用できます。ただし、左側の結合の 2 番目のテーブルのフィルターを単純に結合基準に移動した方がよいでしょう。

于 2016-03-10T16:47:54.610 に答える