2016-11-01 45 views
2

我只想從僱員的姓氏用小寫字母表示的表中選擇行。然而,當我運行下面指定「COLLATE Latin1_General_CS_AS」,查詢結果仍爲「不區分大小寫」

SELECT empid, lastname 
FROM HR.Employees 
WHERE lastname COLLATE Latin1_General_CS_AS LIKE '[a-z]%'; 

查詢它放在員工的姓氏有兩種小寫字母或大寫字母開頭返回的所有行。

我已經指定查詢應區分大小寫,COLLATE Latin1_General_CS_AS,怎麼不過濾出以大寫字母開頭的姓氏?

回答

5

根據SQL Server Books Online,範圍搜索中包含的字符取決於排序規則。整理Latin1_General_CS_AS使用字典順序,因此包含指定範圍的大小寫字符。

指定二進制排序得到你想要的行爲(在97-122碼點範圍的26個ASCII字符):

SELECT empid, lastname 
FROM HR.Employees 
WHERE lastname COLLATE Latin1_General_BIN LIKE '[a-z]%'; 

注意,顯式排序規則導致非sargable表達所以即使存在姓氏上的索引,也需要全表/索引掃描。雖然這可能在這裏沒有幫助,因爲大多數(如果不是全部)姓氏以字母開頭,通常可以爲不區分大小寫的超集添加一個可搜索表達式以促進索引查找。如果使用索引,則與查找謂詞相匹配的行將被區分大小寫的謂詞額外過濾。

SELECT empid, lastname 
FROM HR.Employees 
WHERE lastname COLLATE Latin1_General_BIN LIKE '[a-z]%' 
    AND lastname LIKE '[a-z]%'; 
+0

非常感謝您的回答。從你的答案來看,我認爲通過指定「BIN」,查詢結果仍然是重音敏感的? – Thor

+1

@TonyStark,是的,二進制排序規則使用下劃線代碼點,因此字符在所有方面都很敏感。 –

3

[a-c]將會包含a,b,b,c,所以在這個範圍內給出你想要的每個字母就像波紋管一樣。

select empid, lastname 
from HR.Employees 
where LastName LIKE '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]%' COLLATE Latin1_General_CS_AS; 
1

另一種方法可能是看的第一個字符的ASCII碼:

DECLARE @tbl TABLE(Name VARCHAR(100)); 
INSERT INTO @tbl VALUES('Adam'),('adam') 
         ,('John'),('john') 
         ,('Jane'),('jane') 
         ,('Zaccharias'),('zaccharias'); 
SELECT * 
FROM @tbl 
WHERE ASCII(LEFT(Name,1)) BETWEEN ASCII('a') AND ASCII('z')