2016-03-26 11 views
2

このSQLステートメントがすべてcolumn1の値を選択する方法を説明してください。SQL Server:このSQLステートメントの動作方法

SELECT * 
FROM TABLE 
WHERE (column1 = @brand OR @brand = '*') 

@brand = '*'が、それは@brandを割り当てたときに、私は、考えている:

は、だから、私は@brand = '*'渡す場合、この文はcolumn1内のすべての値を返す

*パラメータ値A、Bがあり、 TRUEとなるので、column1にあるものはtrueとなるため、すべての値を返します。column1

Aを渡した場合、Bの場合はBの値の場合にのみ、Aの値が返されます。

答えて

3

あなたの前提は正しいです。あなたのWHEREステートメントの句を、最も簡単なパスに基づいて順に評価します。

ORがあるので、最初に@brand ='*'句を評価します。その結果がTRUEである場合、WHERE句が満たされ、それ以上の比較は行われません。

FALSEが得られた場合は、column1 = @brandという式の他の句が評価されます。

ただし、SQL Serverでは論理節の短絡や実行順序が保証されていないため、これをSQLで行うのは正しい方法ではないことに注意してください。それはちょうどあなたのケースでそのように動作するが、それは保証されていません。

((@brand = '*') OR (@brand <> '*' AND column1 = @brand)) 
+0

だから、最初にどのようにそれは 'column1'にそれを適用するために知っている、は' true'として '@brand = '*''評価された場合? (それ以上の比較は行われないので)。私はそれが '@brand = '*''を見て、 'column1 = @ brand'ではないと思っています。 – sojim2

+0

@ sojim2それはポイントです - それは' column1'には適用されません。 'OR'節では、一方の側だけが' TRUE'である必要があります - したがって、両方の節が実行される唯一の方法は、一方または両方の文が 'FALSE'である場合です。 – Ruslan

+0

例として、この(非SQL)コードをチェックアウトしてください:http://ideone.com/GmzhHU(SQLは式の中に副作用を許さないので、私はあなたにそのような例を与えることはできません)。 'OR'に基づく' if'文( '||')がどのように存在し、最初の関数だけがどのように実行されるかに注意してください。それは「真」をもたらすので、第2のものは動かす必要はない。プログラムは、最初のものが真であれば、文全体が真(1または0 = 1)であることをすでに知っています。これは短絡*と呼ばれます(ただし、SQL Serverでは同じ方法で短絡が行われることはありませんが、この質問の範囲を超えています)。 – Ruslan

1

このSQL文がどのように動作します:あなたはこのように見てWHERE句を変更する必要がありますか?

論理的に質問していますか?

SQLは3つの論理を使用します。個々の述語は、真、偽、または未知のいずれかと評価できます。

例では、真理値表をORと考えて、述部を結合して全体的な結果を得る方法を調べる必要があります。行が結果に返されるため、全体的な述語がtrueに評価しなければならないWHERE句の文脈において

enter image description here

上記の真理値表は、いずれかの述語が真であることを知ることで十分であることを示しています。したがって、最初のものが真であると評価された場合、2番目のものを評価する必要はありません。これは、短絡回路評価として知られています。

SQL Serverでは、評価の順序または短絡評価のどちらも保証されません。

DECLARE @Table TABLE (
    column1 VARCHAR(50) PRIMARY KEY); 

INSERT INTO @Table 
VALUES  ('brand1'), 
      ('brand2'), 
      ('brand3') 

DECLARE @brand VARCHAR(50) = 'brand1' 

SELECT * 
FROM @Table 
WHERE (column1 = @brand 
      OR @brand = '*'); 

実行プランは、テーブル全体がスキャンされ、次の

enter image description here

と述語が各行で評価を示しています。 SQL Serverは、表示された順序で条件を評価する場合と評価しない場合があり、短絡評価を使用する場合と使用しない場合があります。この情報は私たちには公開されていません。

最初の行が返されます。

enter image description here

効率

上記のクエリのセマンティックは、これが主キーをサポートしている索引に対する簡単な検索で評価することが可能であるべきちょうど

SELECT * 
FROM @Table 
WHERE column1= 'brand1' 

です - テーブル全体をスキャンしません。 SQL Server 2008のから

以降、あなたはそれを実行する前に、この文を再コンパイルし、次の

DECLARE @brand VARCHAR(50) = 'brand1' 

SELECT * 
FROM @Table 
WHERE (column1 = @brand OR @brand = '*') 
OPTION (RECOMPILE) 

を使用することができますし、実行計画をキャッシュしません。つまり、この計画では、具体的な値@brandを考慮に入れることができます。

@brand = '*'の比較は、コンパイル時に行われ、偽であると判断し、述語はcolumn1 = 'brand1'に簡略化される - インデックスは、その特定の値を求めることが可能となります。

enter image description here

関連する問題