2016-05-03 3 views
0

私は表の従業員IDのインデックス付き(ただし、一意ではない)varchar型のフィールドを持っている、とクエリで私はexactly 4 numerical charactersある行を返す必要があるだけでなく、1000数値を返すためにSQLのvarcharフィールドで「XとYの間」を使用しないでください。

の上に、私は上のさまざまな質問を見つけましたフィールドに0〜9文字が含まれているかどうか、またはaz文字などが含まれていないかどうかを確認するための検証メソッドの使用についてはここで説明しますが、これらはこの質問とは無関係です。

背景:

私は次のようにサンプルをセット、さまざまな値を持つテーブルを持っている:

EmployeeID 
---------- 
6745 
EMP1 
EMP2 
1874 
LTST 
5694 
0014 

私は何をしたいのは、すべての値にEMP2EMP1以外を返すです、LTSTおよび0014

私の質問は、私がに使用してはならない理由がありますか?where EmployeeID between '1000' and '9999'のようなWhere節を使用していますか?この従業員の理由はvarcharの列です

これを行うことができれば、従業員IDで注文する必要がありますか、これは関係ありませんか?

+0

リターンEMP1、EMP2、LTSTと0014.除くすべての値を。あなたが間に行うことができますあなたが直面している問題は何ですか? – TheGameiswar

+0

@TheGameiswar私の質問は、このように「間」を使用すべきではない理由があるかどうかです。つまり、数値ではない予期しない結果を返すことができます。私たちはそれらを読む – laurencemadill

答えて

1

例として、次のコードを実行し、あなたはそのSQL ServerがVARCHARとして保存整数としてINTを同じに扱うことはありませんわかります

WITH IntsAsVars 
AS  (
     SELECT var = '1000', 
       int = 1000 
     UNION ALL 
     SELECT var = '100', 
       int = 100 
     UNION ALL 
     SELECT var = '9999', 
       int = 999 
     UNION ALL 
     SELECT var = '99', 
       int = 99 
     UNION ALL 
     SELECT var = '750', 
       int = 750 
     UNION ALL 
     SELECT var = '10', 
       int = 10 
     UNION ALL 
     SELECT var = '2', 
       int = 2 
     ) 
SELECT * 
FROM IntsAsVars 
--WHERE var BETWEEN '2' AND '750' 
/* should return 2, 10, 99, 100 & 750 if it works like INT 
    but does it? */ 
ORDER BY 
     --var ASC, 
     int ASC; 

せずにそれを実行する句には、次のようにSQLを取得する場所サーバーは、私は、「0014」はどこclauから除外されるだろうと信じて、彼らがvarchar型として格納されている2と750:

enter image description here

+0

答えをありがとう。固定長の文字も扱っているため、私のシナリオではこの問題は発生しません。 – laurencemadill

+0

それは十分ですが、 '0001'のような値を停止するのでしょうか? '0011'?等? – Shaneis

2

の間になるように、他のレコードを考慮していませんse between '1000' and '9999'、それが理由です。おそらくbetween '0000' and '9999'はあなたの目的に適しています。あなたはまだテキストに基づいてソートしていることを忘れないでください。 "1_99"のようなエントリがある場合、これは指定されたbetween節でのクエリ結果にも表示されます。より直感的に、

WHERE EmployeeID BETWEEN '1000' AND '9999' AND TRY_CAST(EmployeeID As int) IS NOT NULL 

...または:

あなたが唯一の先行ゼロを除いた4文字の数字を返すために探している場合は、次の追加は十分です

WHERE TRY_CAST(EmployeeID As int) BETWEEN 1000 AND 9999 
+0

はい、「0014」を省略します。この例では、実際に数値であるvarchar値のみを必要とし、実際には4文字で、先行ゼロは除きます。私が心配する '1_99'のような値です – laurencemadill

1

の場合あなたの実際のデータは、文字で始まる非数値の値に関するサンプルデータとまったく同じです。クエリを使用して目的の結果を得ることができます。

ただし、データの並べ替え順序に注意してください。 1ABCのEmployeeIdを取得した場合、返されるデータにはWHERE EmployeeID BETWEEN '1000' AND '9999'が含まれます!

数値以外の値を除外するのに適しています。

追加のORDER BYは結果の順序にのみ影響しますが、条件の評価には影響しません。私は最も簡単な方法は次のように使用するのだと思います

0

select * from yourtable 
where EmployeeID like '[1-9][0-9][0-9][0-9]' 
0

は、この入力を持って言うことができます:

IF OBJECT_ID('tempdb..#test') IS NOT NULL 
    DROP TABLE #test 

CREATE TABLE #test 
(
    EmployeeID VARCHAR(255) 
) 

CREATE CLUSTERED INDEX CIX_test_EmployeeID ON #test(EmployeeID) 

INSERT INTO #test 
VALUES 
('6745'), 
('EMP1'), 
('EMP2'), 
('1874'), 
('LTST'), 
('5694'), 
('1000'), 
('9999'), 
('10L'), 
('187'), 
('9X9'), 
('7est'), 
('1ok'), 
('0_o'), 
('0014'); 

はあなたの声明はまた、 '187'、 '10K' を返します、 '10L'など。 あなたは社員コードが固定長であることを述べているので、あなたがこのようなものを使用でき、:?その理由は何

SELECT * 
FROM #test 
WHERE EmployeeID LIKE '[1-9][0-9][0-9][0-9]' 
関連する問題