2009-03-24 4 views
1

私は以下のT-SQLで真のミステリーを持っています。それはそのままで、DATAP.Private=1またはcast as intRight(CRS,1)で動作します。つまり、DATAP.Private=1のコメントを外した場合、エラーConversion failed when converting the varchar value 'M' to data type intが表示され、そのキャストを削除するとクエリが再び機能します。キャストを適所に置くと、クエリはPrivate=1なしでのみ動作します。私は私の人生のためPrivateは、「M」、これまでですが、Privatebitフィールドでない限りPrivate=1、エラーが発生します、結果セットに何かを追加することができますどのように見ることができませんSQLキャストミステリー

SELECT 
     cast(Right(CRS,1) as int) AS Company 
    , cast(PerNr as int) AS PN 
    , Round(Sum(Cost),2) AS Total_Cost 
FROM 
    DATAP 
    LEFT JOIN BU_Summary ON DATAP.BU=BU_Summary.BU 
WHERE 
    DATAP.Extension Is Not Null 
    --And DATAP.Private=1 
    And Left(CRS,2)='SB' 
    And DATAP.PerNr Between '1' And '9A' 
    and Right(CRS,1) <> 'm' 
GROUP BY 
     cast(Right(CRS,1) as int) 
    , cast(PerNr as int) 
ORDER BY 
    cast(PerNr as int) 

答えて

2

私は過去にこのようなものを見ました。 DATAP.Private = 1句は、Right(CRS,1) <> 'm'フィルタが適用される前にCRSキャストを実行しているクエリプランを生成している可能性があります。

確かにではありません。はそうしていますが、私が書いたT-SQLでも同様の問題がありました。

クエリを機能させるために要素を並べ替えることも、一時的なテーブルまたはテーブル変数にキャストしないデータ値を選択してそこから別のステートメントで選択してストップギャップとしてキャストすることもできます。

実行計画を確認すると、計算されているものについての情報が表示されることがあります。これは、あなたが何を変えるかもしれないかについてより多くのアイデアを与えるかもしれません。

+0

完全一致。 DATAP.Privateがビットフィールドの場合は、ほぼ確実にクラスタードインデックススキャンを生成し、サーバーがスキャンを実行する場合は、すべての変換を一度に適用してフィルタリングします。 – GSerg

0

Private = 1の場合、PerNrはデータ内のキャスト可能な数字以外の数字になることはありません(PerNrは '9A [またはその他のもの]'に等しいので) group byおよびorder by節)。

+0

しかし、PerNrのキャストはPrivate = 1フィルターの有無にかかわらず動作します。これは、プライベート= 1に依存する右(CRS、1)のキャストです。 – ProfK

0

CAST( '9A' AS int)はテストしても失敗します。グループ化とソートのために不要なCASTSを実行しているようです。特にGROUP BYでは、少なくとも最適化の機会はなくなります。

+0

あなたは不要なキャストについて正しいです。私はチェックして以来、私のCSVツールは引用符を付けずにすべての数値を出力します。ここでは数値を引用しないようにintにキャストしていました。 最適化に関しては、これは、このネストされたいくつかのクエリのような醜いクエリを含むAccessクエリに由来します。最適化? – ProfK