SQLServer中使用DISTINCT的大小寫問題

字號:

SQL Server為你提供了在你的數(shù)據(jù)庫中存儲混合大小寫數(shù)據(jù)的能力,但是根據(jù)你怎樣創(chuàng)建數(shù)據(jù)庫,SQL Server將在你給出T-SQL命令時忽視大小寫。你可能面對的一個問題是你想從一個表獲得只包含不同值的列表,來顯示你的表中不同,但是如果你的數(shù)據(jù)庫是按照不區(qū)分大小寫來建立的,那么DISTINCT條件語句不會顯示這些不同,它只會將所有的值放在一起。所以在這方面有什么選擇嗎?
    為了說明這個動作,我們將使用一個區(qū)分大小寫和一個不區(qū)分大小寫的數(shù)據(jù)庫來看看它工作的兩種方式。
    第一組查詢使用了AdventureWorks數(shù)據(jù)庫,它被配置為區(qū)分大小寫。為了得到從你的數(shù)據(jù)庫而來的集合,你可以運行這個查詢:
    SELECT name, collation_name
    FROM master.sys.databases
    我們將查詢AdventureWorks數(shù)據(jù)庫中的Preson.Contact的數(shù)據(jù)。所有的數(shù)據(jù)都是作為混合大小寫來建立的,所以當我們運行這個查詢的時候我們沒有得到重復的值。
    SELECT DISTINCT 10 FirstName
    FROM Person.Contact
    WHERE FirstName LIKE 'A%'
    ORDER BY 1
    如果你更新一條記錄并將FirstName從“Adam”改為“ADAM”,那么當運行這個查詢時我們會獲得兩個不同的值。
    UPDATE Person.Contact
    SET FirstName = 'ADAM'
    WHERE ContactID = 62
    GO
    SELECT DISTINCT 10 FirstName
    FROM Person.Contact
    WHERE FirstName LIKE 'A%'
    ORDER BY 1
    正如你看到的,現(xiàn)在“Adam”和“ADAM”作為不同的值來顯示。
    下一步我們將要做的是在一個不區(qū)分大小寫的數(shù)據(jù)庫中創(chuàng)建一個新表然后從Person.Contact加載所有的數(shù)據(jù)到這個新表中。
    CREATE TABLE Test.dbo.contact (FirstName nvarchar(50))
    GO
    INSERT INTO Test.dbo.contact
    SELECT FirstName FROM Person.Contact
    GO
    SELECT DISTINCT 10 FirstName
    FROM Test.dbo.contact
    WHERE FirstName LIKE 'A%'
    ORDER BY 1
    GO
    當我們運行SELECT查詢時你可以看到輸出將“Adam”和“ADAM”結(jié)合起來,因為不區(qū)分大小寫。
    為了解決這個問題我們可以將這個查詢按照下面的方式修改使得這個收集在FirstName字段上區(qū)分大小寫。
    SELECT DISTINCT 10 FirstName COLLATE sql_latin1_general_cp1_cs_as
    FROM Test.dbo.contact
    WHERE FirstName LIKE 'A%'
    ORDER BY 1
    當這個運行時,我們看到了值“Adam”和“ADAM”。
    所以根據(jù)你的數(shù)據(jù)庫是怎樣建立的,你將能夠或不能看到這個不同。
    為了給你顯示另一個例子,下面是一個快速選擇區(qū)分大小寫或不區(qū)分大小寫選項的方法。
    我們運行的第一個查詢是使用區(qū)分大小寫,所以四條記錄都將顯示出來。
    select distinct (item) COLLATE sql_latin1_general_cp1_cs_as
    FROM (
    select 'abcd' item
    union all select 'ABCD'
    union all select 'defg'
    union all select 'deFg') items
    第二個查詢中不同的是收集的名稱。當這個查詢使用不區(qū)分大小寫時,我們只獲得兩條記錄。
    select distinct (item) COLLATE sql_latin1_general_cp1_ci_ai
    FROM (
    select 'abcd' item
    union all select 'ABCD'
    union all select 'defg'
    union all select 'deFg') items