2011-12-07 9 views
8

ワイルドカード文字の範囲(例:[A-D])が大文字と小文字を区別した照合でどのように動作するかについて、誰もルールを説明できますか?[A-D]などのSQL Serverワイルドカード文字の範囲は、大文字と小文字を区別する照合でどのように機能しますか?

Iは、以下

WHERE CharColumn LIKE '[A-D]%'; 

が大文字A、B、CまたはDで始まるレコードのみを返し、下ケース、B、Cまたはで始まるレコードを除外するだろうと思っただろう

d。

しかし、実際には、大文字のAで始まるレコードだけでなく、Bまたはb、Cまたはc、Dまたはdで始まるレコードも返されるようです。範囲の最初の文字だけが大文字と小文字を区別し、範囲内の残りの文字は大文字と小文字を区別しないようなものです。のみ大文字A、B、CまたはDしかし、私は考えているだろうで始まるレコードを返すない

WHERE CharColumn LIKE '[ABCD]%'; 

を以下一方

、[AD]はに等しいであろう[あいうえお]。

SQL Server 2005とSQL Server 2008 R2で同じ結果が得られます。

例:
(INSERT文は、コンパクトさのためにSQL Server 2008の行のコンストラクタで書かれたそれぞれの値は、SQL Server 2005で動作するスクリプト独自のinsert文与えられた場合。)

CREATE TABLE #TEST_LIKE_Patterns 
    ( 
     ID INT IDENTITY(1,1), 
     CharColumn VARCHAR(100) COLLATE Latin1_General_CS_AS 
    ); 

-------------- 
INSERT INTO #TEST_LIKE_Patterns (CharColumn) 
VALUES ('aaa'), ('aAA'), ('AAA'), ('Aaa'); 
--------------  
INSERT INTO #TEST_LIKE_Patterns (CharColumn) 
VALUES ('bbb'), ('bBB'), ('BBB'), ('Bbb'); 
-------------- 
INSERT INTO #TEST_LIKE_Patterns (CharColumn) 
VALUES ('ccc'), ('cCC'), ('CCC'), ('Ccc'); 
--------------  
INSERT INTO #TEST_LIKE_Patterns (CharColumn) 
VALUES ('ddd'), ('dDD'), ('DDD'), ('Ddd'); 
--------------  
INSERT INTO #TEST_LIKE_Patterns (CharColumn) 
VALUES ('eee'), ('eEE'), ('EEE'), ('Eee'); 
--------------  
INSERT INTO #TEST_LIKE_Patterns (CharColumn) 
VALUES ('fff'), ('fFF'), ('FFF'), ('Fff'); 
-------------- 

-- Raw Data: 
SELECT * 
FROM #TEST_LIKE_Patterns; 

SELECT * 
FROM #TEST_LIKE_Patterns 
WHERE CharColumn LIKE '[A-D]%'; 

-- Results: 
/* 
ID CharColumn 
-------------- 
3 AAA 
4 Aaa 
5 bbb 
6 bBB 
7 BBB 
8 Bbb 
9 ccc 
10 cCC 
11 CCC 
12 Ccc 
13 ddd 
14 dDD 
15 DDD 
16 Ddd 
*/ 


SELECT * 
FROM #TEST_LIKE_Patterns 
WHERE CharColumn LIKE '[ABCD]%';  

-- Results: 
/* 
ID CharColumn 
    -------------- 
3 AAA 
4 Aaa 
7 BBB 
8 Bbb 
11 CCC 
12 Ccc 
15 DDD 
16 Ddd 
*/ 

答えて

11

としてデータを選択しながらMd. Elias Hossain's answerに示されているようにあなたがバイナリ照合を必要とするCOLLATEを使用してください。

パターン構文の範囲は、照合ソート順ルールを無効にするという説明です。範囲検索において

From BOL

、範囲に含まれる文字は、照合のソートルールに応じ を変えることができます。

だから

;WITH T(C) AS 
(
SELECT 'A' UNION ALL 
SELECT 'B' UNION ALL 
SELECT 'C' UNION ALL 
SELECT 'D' UNION ALL 
select 'a' union all 
select 'b' union all 
select 'c' union all 
select 'd' 
) 
SELECT * 
FROM T 
ORDER BY C COLLATE Latin1_General_CS_AS 

戻り

C 
---- 
a 
A 
b 
B 
c 
C 
d 
D 

だから範囲A-Daを除外するが、CS照合下の他の3つの小文字を含みます。

+0

ありがとう、これは私の質問に完全に答えるものです。私は、範囲検索から明らかに任意の結果の背後にある論理を理解しようとしていました。今はとても明確です。乾杯、サイモン。 –

3

を試してみてください
SELECT * 
FROM #TEST_LIKE_Patterns 
WHERE CharColumn LIKE '[A-D]%' COLLATE Latin1_General_BIN; 
0

大文字小文字を区別する照合を使用すると、範囲内にない検索文字列が使用されます。これはうまくいく:

SELECT * 
    FROM #TEST_LIKE_Patterns 
WHERE (
     CharColumn LIKE 'A%' COLLATE Latin1_General_CS_AS 
     OR CharColumn LIKE 'B%' COLLATE Latin1_General_CS_AS 
     OR CharColumn LIKE 'C%' COLLATE Latin1_General_CS_AS 
     OR CharColumn LIKE 'D%' COLLATE Latin1_General_CS_AS 
     ); 

...しかし、明らかにそれは許容されるアプローチではありません!

他にも示唆しているように、範囲にはLatin1_General_BINを使用してください。

+0

テーブルの作成中に「COLLATE Latin1_General_CS_AS」が使用されていて、それが機能していない場合、クエリは同じ結果(変更なし)を提供します。 –

+0

@ Md.EliasHossain:ありがとう、私は正しくテストしませんでした。今更新されました。 – onedaywhen

10

これは、いずれかの方法で行うことができます

COLLATEを使用して表を作成しながら、表を次のように作成します。

CREATE TABLE #TEST_LIKE_Patterns 
( 
    ID INT IDENTITY(1,1), 
    CharColumn VARCHAR(100) COLLATE Latin1_General_BIN 
); 

b。

SELECT * 
FROM #TEST_LIKE_Patterns 
WHERE CharColumn LIKE '%[A-D]%' COLLATE Latin1_General_BIN; 
+0

ありがとう、WHERE句で照合順序を指定できることはわかりませんでした。これは私が設計していないデータベースを照会するときに最も役立ちます。また、大文字と小文字を区別するのではなく、バイナリ照合を使用することは考えていませんでした。乾杯、サイモン –

+0

'Latin1_General_CS_AS'の代わりに' Latin1_General_BIN'を使用しました –

関連する問題