2017-04-03 4 views
1

2つの列vwを一緒に追加すると、一方または両方の被加数がNULLの場合、行の結果はNULLになります。意味あり。しかし、私がSUM(v)の列を合計すると、NULLであっても数字の結果が出ます。これは実用的な喜びですか?それとも理論的正当性があるのでしょうか?ここ列の追加とNULL値の列の合計の間のSQLの不一致

は(MySQLとSQLiteの)を明確にする例である:

CREATE TABLE x0 (
    id INTEGER 
, v  DOUBLE 
, w  DOUBLE 
); 

INSERT INTO x0 VALUES 
    (1, 1,  1) 
, (2, 1,  1) 
, (3, NULL,  1) 
, (4, 1, NULL) 
, (5, NULL, NULL) 
; 

-- NULL if summand is NULL 
SELECT v+w 
FROM x0 
; 
-- v+w 
-- 2 
-- 2 
-- \N 
-- \N 
-- \N 

-- NULL if summand is NULL 
SELECT id, v+w, SUM(v+w) 
FROM x0 
GROUP BY id 
; 
-- id v+w SUM(v+w) 
-- 1 2 2 
-- 2 2 2 
-- 3 \N \N 
-- 4 \N \N 
-- 5 \N \N 


-- There is numeric results even if some summands are NULL  
SELECT SUM(v), SUM(w) 
FROM x0 
; 
-- SUM(v) SUM(w) 
-- 3  3 
+1

SQLは、健全で一貫した理論上の基礎を持っていません。その標準がどのように操作を定義しているかを受け入れるだけです。 「理論的に」、「NULL」値が不定であるため、いずれかの引数が「NULL」である場合、値は「NULL」でなければならない。 –

+0

@ GordonLinoff SQLは集合理論に基づいていると私は考えました。したがって、妥当性のために、いくつかのケースでは、例えば、「SUM」のような関数を使用して、数学的な徹底を残すように思われる。 – giordano

+1

標準SQLは、集計関数内のNULLを単純に無視/削除します。さもなければ、 'MIN(COALESCE(mycolumn、9999999)'のようなNULL可能な列にCOALESCEを使う必要があります。返された9999999が実際に最小値かNULL置換かどうかを知るのは難しいです。 – dnoeth

答えて

1

ISO/IEC 9075:1992 Database Language SQLは、セクション6.5(<セット機能仕様>)、一般規則で述べているのmysqlに適切な機能をヌル値

などを管理する必要があります、1)b):

TXを、T の各行に<値式を適用してNULL値を除いた の結果である単一列テーブルにします。

それはすべてです。したがって、集約関数はNULLを無視する必要がありますが、正式には正当化はありません。

この動作は、最初のSQL実装(IBM System R、Oracle V2)に戻ります。設計者はおそらくこれが良い考えだと考えていました。そして後で、後方互換性を破ることを望んでいた人はいません。

他の場合と同様に、SQL's handling of NULL valuesは矛盾しており、時には移植性がありません。

関連する問題