4

SELECT別のステートメントの結果からa を実行する方法を理解したと思っていましたがSELECT、理解できない範囲のぼやけがあるようです。SQL Server 2008R2 を使用しています。

例を挙げて説明するのが最も簡単です。

単一の nvarchar 列を含むテーブルを作成します - 単一のテキスト値といくつかの数値を含むテーブルを読み込みます。

CREATE TABLE #temptable( a nvarchar(30) ); 
INSERT INTO #temptable( a )
    VALUES('apple');
INSERT INTO #temptable( a )
    VALUES(1);
INSERT INTO #temptable( a )
    VALUES(2);

select * from #temptable;

これは以下を返します: apple, 1, 2

IsNumeric数値にキャストできるテーブルの行のみを取得するために使用します。これにより、テキスト値がapple残ります。これはうまくいきます。

    select cast(a as int) as NumA
    from #temptable 
    where IsNumeric(a) = 1 ;

これは以下を返します:1, 2

ただし、まったく同じクエリを内部選択として使用し、数値句を実行しようとすると、値 'apple' を data type にWHERE変換できないと言って失敗します。どのようにして「りんご」という値を取り戻したのでしょうか??nvarcharint

    select 
        x.NumA
    from 
    (
        select cast(a as int) as NumA
        from #temptable 
        where IsNumeric(a) = 1 
    ) x
    where x.NumA > 1
    ;

WHERE失敗したクエリは、句がなくても問題なく機能することに注意してください。

    select 
        x.NumA
    from 
    (
        select cast(a as int) as NumA
        from #temptable 
        where IsNumeric(a) = 1 
    ) x
    ;

これは非常に驚くべきことです。何が得られないのですか?ティア

4

3 に答える 3

0

推定実行プランを見ると、内部クエリが外部クエリに最適化され、WHERE句が組み合わされていることがわかります。

CTEを使用して操作を分離することは機能します(SQL Server 2008 R2の場合)。

declare @temptable as table ( a nvarchar(30) );  
INSERT INTO @temptable( a ) 
    VALUES ('apple'), ('1'), ('2'); 

with Numbers as (    
  select cast(a as int) as NumA 
    from @temptable  
      where IsNumeric(a) = 1  
  )
  select * from Numbers
于 2012-09-18T15:15:33.800 に答える
0

これを取得する理由は、公正かつ単純です。クエリが実行されると、いくつかの手順が実行されます。これは、解析、代数化、最適化、およびコンパイルです。この場合の algebrize 部分は、このクエリに必要なすべてのオブジェクトを取得します。最適化では、これらのオブジェクトを使用して、コンパイルおよび実行される最適なクエリ プランを作成します...

したがって、その部分を調べると、#temptable でテーブル スキャンが実行されることがわかります。そして #temptable は、テーブルを作成した方法として定義されています。それに対して何らかの計算を行うことは別のことです.....列にはまだnvarcharデータ型があります..

これがどのように機能するかを知るには、クエリの読み方を知る必要があります。最初にすべてのオブジェクトが (テーブル、内部結合テーブルから) 取得され、次に述語 (where、on)、次にグループ化など、次に列の選択 (キャストを使用)、次に orderby が取得されます。

それを念頭に置いて、選択の組み合わせがある場合、オプティマイザーはそれをそのように処理します.選択はクエリの from および join 部分に従属しているため、このエラーが発生する理由になります.

私はそれを少し明確にしたことを願っていますか?

于 2012-10-02T13:46:02.053 に答える
0

オプティマイザーは、データを取得するための最もコスト効率の高いプランを生成するために、クエリ プラン内の式を自由に移動できます (述語の評価順序は保証されません)。次のようなケース式を使用すると、ELSE句がない場合にNULLが生成されるため、APPLEが取り出されると思います

#temptable から a を選択し、 isnumeric(a) = 1 の場合は end > 1 の場合

于 2014-07-09T13:28:03.950 に答える