2011-08-10 12 views
2

は私が名前XYZによってvarchar列とその列の値を持っている私ははそれがない

CASE 
    WHEN XYZ > '9.0' THEN 
    'DONE' 
    WHEN XYZ < '7.0' THEN 
    'NOT DONE' 
    WHEN XYZ BETWEEN '7.0' AND '9.0' THEN 
    'NULL' 
    END 

のようなcase文の何かを書くとき

XYZ 
10.2 
9.0 
97.32 

のようなものですvarchar列に小数点以下の値を比較します値と比較する。これを解決するために何をすべきか?

+2

「これを解決するにはどうすればよいですか」数値データ型を使用して数値を格納します。 'varchar'を使う理由は何ですか?これは変更できますか?そうでない場合は、列に数値以外の値がありますか? –

+0

coloumnデータ型はvarcharにあります。coloumnには数値以外の値はありません。 – palum

+1

私はそれが 'varchar'だと知っています。あなたはまた、それを修正するために何をすべきか尋ねます。回答。より適切なデータ型を使用してください。 –

答えて

0

キャストを行う前にデータが数値かどうかを判断する必要があります。デナリはTRY_CONVERT機能を持っていますが、以前のバージョンでは、あなたはメインCASEに組み込まれたり

DECLARE @YourTable TABLE 
(
XYZ VARCHAR(50) 
) 

INSERT INTO @YourTable 
SELECT 'foo' AS XYZ 
UNION ALL 
SELECT '8.9' 
UNION ALL 
SELECT '9.1' 
UNION ALL 
SELECT '6.5' 

SELECT 
CASE 
    WHEN _XYZ > 9 THEN 
    'DONE' 
    WHEN _XYZ < 7 THEN 
    'NOT DONE' 
    END 
FROM @YourTable 
CROSS APPLY(SELECT CASE WHEN ISNUMERIC(XYZ + 'e0') = 1 
      THEN CAST(XYZ AS NUMERIC(18,8)) END) CA(_XYZ) 
2

データが正常であることがわかっている場合は、フィールドでキャスト(または変換)ステートメントを実行できます。あなたはまた、ノートの「9.0」 の前後に引用符を失うべきで
CASE WHEN CAST(XYZ AS decimal) > 9.0 THEN 'DONE' WHEN CAST(XYZ AS decimal) < 7.0 THEN 'NOT DONE' WHEN CAST(XYZ AS decimal) BETWEEN 7.0 AND 9.0 THEN 'NULL' END

注意、キャスト操作は、フィールド全体に対して実行されようとしています。これは、比較を行う前に変換を行うためにテーブル全体をスキャンする必要があるため、インデックスの使用を無駄にします。これは、適度に大きなテーブル(つまり、10〜100kレコード)に対しても重大なパフォーマンスの影響を与える可能性があります。

+0

はい、これは私の心の中に打ち込まれた最初のものでした。私のパッケージを実行しようとしている間、走るのに時間がかかります。だから私はこれは私の場合にもうまくいかないと思います。 – palum

2

実際に列が数値のみを表し、数値以外のものを含むことは決してない場合は、列をより適切な型に変換する1回の操作を行います。データの性質に応じて、正確なタイプとおおよそのタイプのいずれかを選択する必要があります。つまり、decimalfloat/realです。前者の場合、正しい精度と位取り(小数点以下の桁数)を選択する必要があります。

変換自体はこのように、基本的になります。

再び
ALTER TABLE atable 
ALTER COLUMN XYZ decimal(15, 2) 

を、あなたはそれ以外のステートメントが失敗しようとしている、列には非数の値がないことを確認する必要があります。

+0

私は変更ステートメントを実行する権限を持っていません。そして、私はまた、そのcoloumnに存在するいくつかの他のデータを見つけることができました。したがって、castステートメントはdecimal、float、realなどの他のデータ型でもキャストできません – palum

0
WHEN ISNUMERIC(XYZ) = 0 
           THEN 'DONE' 
       WHEN CONVERT(DECIMAL,XYZ) > 9 
           THEN 'NOT DONE' 
       WHEN CONVERT(DECIMAL,XYZ) < 7.0 
           THEN 'SOMETIMES DONE' 
       WHEN CONVERT(DECIMAL,XYZ) BETWEEN 7.0 AND 9.0 
           THEN 'EVERYTIME DONE' 
       WHEN ISNULL(XYZ,'') = '' 
           THEN 'NONE' 
END 

ヤフーatlastが行われ、以下のようにして分離することができどちらかCASE WHEN ISNUMERIC(XYZ + 'e0') = 1ステートメントを使用する必要があります!これは私のために働いた。 あなたの助けと役に立つアドバイスありがとう あなたのすべての時間をappretiate。

関連する問題