1

SQL言語の弁護士が助けてくれることを望んでいるSQL標準について質問があります。

特定の表現が機能しないだけです。62 / 0、 例えば。SQL標準では、式が同様の方法で失敗する可能性のあるかなりの数の方法が指定されています。多くの言語は、特別な例外的なフロー制御、つまりボトム疑似値を使用してこれらの式を処理します。

t2つの列(のみ)がxあり、yそれぞれがタイプのテーブルがありますint。関連性はないと思いますが、明確にするために、それ(x,y)がの主キーであるとしましょうt。このテーブルには、次の値(のみ)が含まれています。

x    y
7    2
3    0
4    1
26   5
31   0
9    3

SELECTゼロによる除算を伴う可能性のあるこのテーブルで動作する式のSQL標準には、どのような動作が必要ですか?または、1つの動作が必要ない場合、どのような動作が許可されますか?

たとえば、次のselectステートメントにはどのような動作が必要ですか?

簡単なもの:

SELECT x, y, x / y AS quot
FROM t

難しいもの:

SELECT x, y, x / y AS quot
FROM t
WHERE y != 0

さらに難しいもの:

SELECT x, y, x / y AS quot
FROM t
WHERE x % 2 = 0

実装(たとえば、このクエリのより複雑なバージョンで、制限を拡張機能内に移動できることを認識できなかったもの)は、このクエリに応答してゼロ除算エラーを生成することを許可されますか?制限を実行してそれを実現する前に、拡張の一部として除算3しますか?これは、たとえば、拡張機能が小さなテーブル上にある場合に重要になる可能性がありますが、大きなテーブルと結合され、大きなテーブルのデータに基づいて制限された結果、すべての行が制限されてしまいます。ゼロ除算が必要です。03 % 2 = 1

tに数百万の行があり、この最後のクエリがテーブルスキャンによって実行された場合、実装は、ゼロ値を持つxの1つの偶数値に遭遇したときに、終わり近くでゼロによる除算を検出する前に、最初の数百万の結果を返すことが許可されますか? yの?バッファリングする必要がありますか?

さらに悪いケースがあります。これについて考えてみてください。セマンティクスによっては、ブール短絡が台無しになったり、制限に4値ブールロジックが必要になる場合があります。

SELECT x, y
FROM t
WHERE ((x / y) >= 2) AND ((x % 2) = 0)

テーブルが大きい場合、この短絡の問題は非常に深刻になる可能性があります。テーブルに100万行があり、そのうちの1つに0の除数があるとします。標準では、次のセマンティクスが示されます。

SELECT CASE 
       WHEN EXISTS 
            (
                SELECT x, y, x / y AS quot
                FROM t
            )
       THEN 1
       ELSE 0
       END AS what_is_my_value

この値は、エラーである結果の空または非空に依存するため、おそらくエラーであるように思われますが、これらのセマンティクスを採用すると、ここでテーブルスキャンを短絡するオプティマイザーが禁止されるように見えます。この存在クエリでは、底なしの行が1つ存在することを証明する必要がありますか、それとも底付きの行が存在しないことを証明する必要がありますか?

仕様の関連部分が見つからないようですので、ここでのガイダンスをいただければ幸いです。

4

1 に答える 1

1

私が使用したSQLのすべての実装は、0による除算を即値NaNまたは。として扱い#INFます。分割は、実装自体ではなく、フロントエンドによって処理されることになっています。NaNクエリはボトムアウトすべきではありませんが、この場合、結果セットが返される必要があります。したがって、結果セットと同時に返され、ユーザーに特別な警告やメッセージが表示されることはありません。

とにかく、これを適切に処理するには、次のクエリを使用します。

select
   x, y, 
   case y 
       when 0 then null 
       else x / y 
   end as quot
from
   t

あなたの最後の質問に答えるために、この声明:

SELECT x, y, x / y AS quot
FROM t

これを返します:

x    y   quot
7    2    3.5
3    0    NaN
4    1      4
26   5    5.2
31   0    NaN
9    3      3

したがって、商が何であるかに関係なく、のexistsすべての行が見つかります。t

さらに、私はあなたの質問をもう一度読んでいて、私がwhere条項について話し合っていなかったことに気づきました(恥ずべきことです!)。where句、またはpredicate、は、列が計算される前に常に適用する必要があります

このクエリについて考えてみてください。

select x, y, x/y as quot from t where x%2 = 0

レコード(3,0)がある場合、where条件を適用し、。をチェックします3 % 2 = 0。含まれていないため、そのレコードは列の計算に含まれず、そのままの場所に残されます。

于 2009-07-17T12:00:07.373 に答える