9

これが機能しないのはなぜですか?

select *
from
(
    select membership_number
    from members
    where membership_number not like '%[^0-9]%'
) mem
where cast(membership_number as int) > 2

SQL Fiddle デモを参照してください。

サブクエリは数値以外のデータを除外する必要があり、外側のクエリはこれを整数にキャストして、2 より大きいものを探すことができるようにします。

外側のクエリの where 句を最初に実行しているようです。どうすればこれを回避できますか?

4

5 に答える 5

2

多分それ:

select *
from
(
    select
        membership_number
    from
        members
    where
        membership_number not like '%[^0-9]%'
) mem
where Try_Convert(int, membership_number) > 2
于 2013-04-10T01:09:52.250 に答える
1

以前に問題がありました。私がしたことは:

1、次のことを行うビューを持つことができます:

select membership_number
    from members
    where membership_number not like '%[^0-9]%'

2、または一時テーブルを使用する

3、またはユースケース節:

select *
from
(
    select membership_number
    from members
    where membership_number not like '%[^0-9]%'
) mem
where (CASE WHEN ISNUMERIC(membership_number) THEN cast(membership_number as int) ELSE 0 END) > 2

エレガントな解決策はありませんでしたが、これが役立つことを願っています

于 2013-04-10T01:10:44.807 に答える
1

非常に興味深いことに、これを SQL Server で再現しようとしたところ、次のことがわかりました。クエリが失敗せず、実行計画を確認できるようにするためだけに、クエリをシンプルに変更しました。

select *
from
(
    select membership_number
    from members
    where membership_number not like '%[^0-9]%'
) mem
where membership_number > '2'

実行計画には、述語を含むテーブル スキャンがあります。

[master].[dbo].[members].[membership_number]>'2' 
    AND NOT [master].[dbo].[members].[membership_number] like '%[^0-9]%'

これは、SQL 最適化エンジンがこのように動作するためです (誰かが言ったように、where 句の順序を保証できる人はいません)。おそらくそれを修正する方法の1つは、前にISNUMERICを使用することです

select *
from
(
    select membership_number
    from members
    where membership_number not like '%[^0-9]%'
) mem
where ISNUMERIC(mem.membership_number) = 1 and cast(mem.membership_number as int) > 2
于 2013-04-10T01:32:14.923 に答える
0

これを試すことができます。次のクエリで最初の条件が実行され、失敗すると2番目の条件は実行されません

select
    membership_number
  from
    members
where 
isnumeric(membership_number) = 1 and 
cast(membership_number as int) > 2

クエリが機能しない理由に答えるには、こちらの説明を確認してください

于 2013-04-10T04:06:26.897 に答える
0

コメントは、実行計画が (時々) のcast前にを評価する方法を説明しますlike。ステートメントは評価のcase順序を助けることができますが、Adams が言及しているように、この方法でさえ 100% ではありません。

select  *
from    members
where   case
            when membership_number like '%[^0-9]%' then 0
            when cast(membership_number as int) > 2 then 1
            else 0
        end = 1
于 2013-04-10T01:14:04.887 に答える