2016-06-16 8 views
1

比較演算子修飾子ALLが期待どおりに機能しないようです。私はMicrosoft SQL Server 2008 R2 Management Studio(v10.50.4000.0)を使用しています。SQL Serverの比較演算子修飾子ALLが機能しません。

declare @AllTest table 
(
    ID int identity, 
    Crew int, 
    Iteration int, 
    Value varchar(200) 
) 

insert @AllTest 
values 
    (1, 1, 'a'), 
    (2, 1, 'b'), 
    (3, 1, NULL), 
    (1, 2, 'd'), 
    (1, 3, 'e'), 
    (3, 2, NULL), 
    (2, 2, 'a'), 
    (2, 3, 'b'), 
    (1, 4, NULL), 
    (1, 5, 'f') 

select 
    * 
from 
    @AllTest 
where 
    1 = 1 
    and Crew = 1 
    and Value is not NULL 

select 
    * 
from 
    @AllTest 
where 
    1 = 1 
    and Crew = 1 
    and Value is not NULL 
    and Iteration = all(select v from (values (1),(2),(3)) as t(v)) 

select 
    * 
from 
    @AllTest 
where 
    1 = 1 
    and Crew = 1 
    and Value is not NULL 
    and Iteration != all(select v from (values (1),(2),(3)) as t(v)) 

ここで、 'Iteration = all'は結果を返しませんが、それはすべきです。 「Iteration!= all」というクエリは、期待通りに機能します。 (しかし、そのような結果は、 '反復ではない'によって、そして値を提示するためにテーブル値コンストラクタやユニオンのようなものを使用してサブクエリを使用する必要はありません)。すべてが表示されているように動作せず、 '反復=すべて(1,2,3)'または '反復!=すべて(1,2,3)'などの単純な式が無効であることは本当に奇妙なようです。

select 
    * 
from 
    @AllTest 
where 
    1 = 1 
    and Crew = 1 
    and Value is not NULL 
    and Iteration != all(1,2,3) 

これは、私のバージョンのSQL Serverには問題がありますか?何が欠けていますか?

ALLが動作しない場合、ALLを使用して生成する必要がある結果を返すようにクエリを構成する最も良い代替方法は何ですか?

編集: 私は予想される結果に関して私の質問を明確にしていないことをお詫びします。値のNULLとIterationが1に、行数が2と3で行がなくなった行がある場合にのみ結果を返す方法を探しています。

私はそれが理にかなっていると思います。

また、 'Iteration = all'が1行を探しているのを見て、意味的に意味が分かりやすく誤った構文と見なされる 'Iteration in all'を試しました。

+0

あなたは結果は次のようになり期待していた、あなたが代替をしたい場合は、なぜ、私はあなたがのいくつかの並べ替えを望むかもしれないと想像してるかを説明する必要があります関係分割クエリ。 –

答えて

1
Iteration = all(select v from (values (1),(2),(3)) as t(v)) 

Iteration = 1 AND Iteration = 2 AND Iteration = 3 

WHEREは、一度に一行に動作します。任意の単一の行について上記のことが真実であることは不可能であり、従って結果はない。


あなたの編集後、ご希望の動作を得るための一つの方法は、

;WITH CTE 
    AS (SELECT * 
     FROM @AllTest 
     WHERE Crew = 1 
       AND Value IS NOT NULL) 
SELECT * 
FROM CTE 
WHERE NOT EXISTS (SELECT v 
        FROM (VALUES (1), 
            (2), 
            (3)) AS t(v) 
        EXCEPT 
        SELECT c2.Iteration 
        FROM cte c2) 
+0

ご協力ありがとうございます。私は調査して、最良の解決策にあなたが言及した関係分割を含むことを決めました。私はこれまでにそれを聞いたことがなかった。指定された列に括弧内のステートメント内にリストされているすべての値の行があることを保証するクエリを構築する簡単な方法がないことは、まだ奇妙に思えます。あなたが説明した方法でALLという言葉を適用していることを理解しています。現在解釈されているため、 '= all(1,2,3)'は決して真ではないので、実行計画生成プログラムは、より複雑で複雑な構築を避ける意味でそうするべきです。 – Erg

0

である私は、あなたがどれ代わりにALLのを使用したいと思います。 >と<のすべての作品、例:

select 
    * 
from @AllTest 
where 1 = 1 
    and Crew = 1 
    and Value is not NULL 
    and Iteration > all(select v from (values (1),(2),(3)) as t(v)) 

fを使ってレコードを返します。

ID Crew Iteration Value 
10 1   5   f 

これは任意である:

select 
    * 
from @AllTest 
where 1 = 1 
    and Crew = 1 
    and Value is not NULL 
    and Iteration = Any(select v from (values (1),(2),(3)) as t(v)) 

ID Crew Iteration Value 
1 1 1 a 
4 1 2 d 
5 1 3 e 
+0

'= Any'はちょうど' IN' –

+0

この記事に記載されているとおり、正しいです。 https://technet.microsoft.com/en-us/library/ms187074(v=sql.105).aspx –