एक्सेंट सेंसिटिव सॉर्ट


19

इन दोनों SELECTकथनों का परिणाम भिन्न क्रम में क्यों होता है?

USE tempdb;
CREATE TABLE dbo.OddSort 
(
    id INT IDENTITY(1,1) PRIMARY KEY
    , col1 NVARCHAR(2)
    , col2 NVARCHAR(2)
);
GO
INSERT dbo.OddSort (col1, col2) 
VALUES (N'e', N'eA')
    , (N'é', N'éB')
    , (N'ë', N'ëC')
    , (N'è', N'èD')
    , (N'ê', N'êE')
    , (N'ē', N'ēF');
GO

SELECT * 
FROM dbo.OddSort 
ORDER BY col1 COLLATE Latin1_General_100_CS_AS;
╔════╦══════╦══════╗
║ आईडी ║ col1 ║ col2 ║
╠════╬══════╬══════╣
║ 1 ║ e ║ eA ║
║ 2 ║ ║ ║ éB ║
║ 4 ║ è ║ èD should - id 3 होनी चाहिए?
║ 5 ║ ê ║ êE ║
║ 3 ║ ë ║ ëC ║
║ 6 ║ ║ ║ ēF ║
╚════╩══════╩══════╝
SELECT * 
FROM dbo.OddSort 
ORDER BY col2 COLLATE Latin1_General_100_CS_AS;
╔════╦══════╦══════╗
║ आईडी ║ col1 ║ col2 ║
╠════╬══════╬══════╣
║ 1 ║ e ║ eA ║
║ 2 ║ ║ ║ éB ║
║ 3 ║ ë ║ ëC ║
║ 4 ║ è ║ èD ║
║ 5 ║ ê ║ êE ║
║ 6 ║ ║ ║ ēF ║
╚════╩══════╩══════╝

जवाबों:


13

यह सवाल डेटाबेस से संबंधित नहीं है, लेकिन यूनिकोड हैंडलिंग और नियमों पर अधिक है।

Https://docs.microsoft.com/en-us/sql/t-sql/statements/windows-collation-name-transact-sql Latin1_General_100_CS_AS के आधार पर इसका अर्थ है: "Collation लैटिन 1 जनरल डिक्शनरी सॉर्टिंग नियमों और कोड पेज पर मैप्स का उपयोग करता है। 1252 "जोड़ा गया CS = केस सेंसिटिव और AS = एक्सेंट सेंसिटिव के साथ।

विंडोज कोड पेज 1252 और यूनिकोड ( http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT ) के बीच मैपिंग उन सभी वर्णों के लिए समान मान दिखाती है जिनसे हम व्यवहार कर रहे हैं (मैक्रोन के साथ ई को छोड़कर) Microsoft मैपिंग में मौजूद नहीं है, इसलिए इस मामले में कोई भी विचार नहीं करता है), इसलिए हम अभी के लिए यूनिकोड टूल और शब्दावली पर ध्यान केंद्रित कर सकते हैं।

सबसे पहले, हमें ठीक से बताएं कि हम आपके सभी तार के लिए क्या व्यवहार कर रहे हैं:

0065  LATIN SMALL LETTER E
0041  LATIN CAPITAL LETTER A
00E9  LATIN SMALL LETTER E WITH ACUTE
0042  LATIN CAPITAL LETTER B
00EB  LATIN SMALL LETTER E WITH DIAERESIS
0043  LATIN CAPITAL LETTER C
00E8  LATIN SMALL LETTER E WITH GRAVE
0044  LATIN CAPITAL LETTER D
00EA  LATIN SMALL LETTER E WITH CIRCUMFLEX
0045  LATIN CAPITAL LETTER E
0113  LATIN SMALL LETTER E WITH MACRON
0046  LATIN CAPITAL LETTER F

यूनिकोड Collation एल्गोरिथ्म यहाँ वर्णित है: https://www.unicode.org/reports/tr10/

धारा 1.3 "प्रासंगिक संवेदनशीलता" पर एक नज़र डालें जो बताती है कि छंटाई एक के बाद एक चरित्र पर निर्भर नहीं हो सकती क्योंकि कुछ नियम संदर्भ के प्रति संवेदनशील होते हैं।

1.8 में इन बिंदुओं पर भी ध्यान दें:

कोलाज स्ट्रिंग्स की संपत्ति नहीं है। टकराव आदेश को सामान्य रूप से संघनन या विकल्प संचालन के तहत संरक्षित नहीं किया जाता है।

डिफ़ॉल्ट रूप से, एल्गोरिथ्म तीन पूरी तरह से अनुकूलन स्तरों का उपयोग करता है। लैटिन लिपि के लिए, ये स्तर मोटे तौर पर निम्न के अनुरूप हैं:

alphabetic ordering
diacritic ordering
case ordering.

लेकिन एल्गोरिथ्म अपने आप में थोड़ा घना है। इसका सार है: संक्षेप में कहा गया है, यूनिकोड Collation Algorithm एक इनपुट यूनिकोड स्ट्रिंग और एक Collation Element Table लेता है, जिसमें पात्रों के लिए डेटा मैपिंग है। यह एक सॉर्ट कुंजी बनाता है, जो अहस्ताक्षरित 16-बिट पूर्णांक की एक सरणी है। तब उत्पादित दो या अधिक सॉर्ट कुंजी तब बाइनरी-तुलना की जा सकती हैं, जिससे वे उत्पन्न किए गए तारों के बीच सही तुलना कर सकें।

आप यहाँ विशिष्ट लैटिन छँटाई के नियम देख सकते हैं: http://developer.mimer.com/collations/charts/latin.htm या अधिक सीधे और विशेष रूप से MS SQL के लिए: http://collation-charts.org/mssql/mssll। 0409.1252.Latin1_General_CS_AS.html

के लिए eचरित्र यह पता चलता है:

e ई E E è È ê ë ë É

यह आपके परिणामों की व्याख्या करता है जब आदेश को col1छोड़कर explains कोड पेज 1252 में मौजूद नहीं होता है, इसलिए मेरे पास बिल्कुल कोई विचार नहीं है कि यह इसके साथ क्या करता है।

या यदि हम http://www.unicode.org/Public/UCA/latest/allkeys.txt पर DUCET के कुंजी मान का उपयोग करके हाथ से यूनिकोड एल्गोरिथ्म करते हैं :

चरण 1: सामान्यीकरण फॉर्म डी, इसलिए प्रत्येक मामला बनता है:

e => U+0065
é => U+0065 U+0301
ë => U+0065 U+0308
è => U+0065 U+0300
ê => U+0065 U+0302
ē => U+0065 U+0304

चरण 2, कोलाज सरणियों का निर्माण करें (फ़ाइल में खोज allkeys.txt)

e => [.1D10.0020.0002]
é => [.1D10.0020.0002] [.0000.0024.0002]
ë => [.1D10.0020.0002] [.0000.002B.0002]
è => [.1D10.0020.0002] [.0000.0025.0002]
ê => [.1D10.0020.0002] [.0000.0027.0002]
ē => [.1D10.0020.0002] [.0000.0032.0002]

चरण 3, प्रपत्र सॉर्ट कुंजियाँ (प्रत्येक स्तर के लिए, प्रत्येक कोलाज सरणी के अंदर प्रत्येक मान लें, फिर परिसीमनकर्ता के रूप में 0000 डालें और अगले स्तर के लिए फिर से शुरू करें)

e => 1D10 0000 0020 0000 0002
é => 1D10 0000 0020 0024 0000 0002 0002
ë => 1D10 0000 0020 002B 0000 0002 0002
è => 1D10 0000 0020 0025 0000 0002 0002
ê => 1D10 0000 0020 0027 0000 0002 0002
ē => 1D10 0000 0020 0032 0000 0002 0002

चरण 4, सॉर्ट कुंजियों की तुलना करें (एक-एक करके प्रत्येक मान की सरल बाइनरी तुलना): चौथा मूल्य उन सभी को सॉर्ट करने के लिए पर्याप्त है, इसलिए अंतिम क्रम बन जाता है:

e
é
è
ê
ë
ē

उसी तरह आदेश देने के लिए col2:

चरण 1: एनएफडी

eA => U+0065 U+0041
éB => U+0065 U+0301 U+0042
ëC => U+0065 U+0308 U+0043
èD => U+0065 U+0300 U+0044
êE => U+0065 U+0302 U+0045
ēF => U+0065 U+0304 U+0046

चरण 2: Collation arrays

eA => [.1D10.0020.0002] [.1CAD.0020.0008]
éB => [.1D10.0020.0002] [.0000.0024.0002] [.1CC6.0020.0008]
ëC => [.1D10.0020.0002] [.0000.002B.0002] [.1CE0.0020.0008]
èD => [.1D10.0020.0002] [.0000.0025.0002] [.1CF5.0020.0008]
êE => [.1D10.0020.0002] [.0000.0027.0002] [.1D10.0020.0008]
ēF => [.1D10.0020.0002] [.0000.0032.0002] [.1D4B.0020.0008]

चरण 3: सॉर्ट कुंजी

eA => 1D10 1CAD 0000 0020 0020 0000 0002 0008
éB => 1D10 1CC6 0000 0020 0024 0020 0000 0002 0002 0008
ëC => 1D10 1CE0 0000 0020 002B 0020 0000 0002 0002 0008
èD => 1D10 1CF5 0000 0020 0025 0020 0000 0002 0002 0008
êE => 1D10 1D10 0000 0020 0027 0020 0000 0002 0002 0008
ēF => 1D10 1D4B 0000 0020 0032 0020 0000 0002 0002 0008

चरण 4: सॉर्ट कुंजी की तुलना करें: दूसरा मान उन सभी को सॉर्ट करने के लिए पर्याप्त है, और यह वास्तव में पहले से ही बढ़ते क्रम में है, इसलिए अंतिम आदेश वास्तव में है:

eA
éB
ëC
èD
êE
ēF

अपडेट : सोलोमन रुट्स्की तीसरे मामले को जोड़ना, जो कि अंतरिक्ष के कारण पेचीदा है जो नए नियमों को सक्षम बनाता है (मैंने "गैर-इग्नोर केस" चुना):

चरण 1, एनएफडी:

è 1 => U+0065 U+0300 U+0020 U+0031
ê 5 => U+0065 U+0302 U+0020 U+0035
e 2 => U+0065 U+0020 U+0032
é 4 => U+0065 U+0301 U+0020 U+0034
ē 3 => U+0065 U+0304 U+0020 U+0033
ë 6 => U+0065 U+0308 U+0020 U+0036

चरण 2, कोलाज सरणियों का निर्माण करें:

è 1 => [.1D10.0020.0002] [.0000.0025.0002] [*0209.0020.0002] [.1CA4.0020.0002]
ê 5 => [.1D10.0020.0002] [.0000.0027.0002] [*0209.0020.0002] [.1CA8.0020.0002]
e 2 => [.1D10.0020.0002] [*0209.0020.0002] [.1CA5.0020.0002]
é 4 => [.1D10.0020.0002] [.0000.0024.0002] [*0209.0020.0002] [.1CA7.0020.0002]
ē 3 => [.1D10.0020.0002] [.0000.0032.0002] [*0209.0020.0002] [.1CA6.0020.0002]
ë 6 => [.1D10.0020.0002] [.0000.002B.0002] [*0209.0020.0002] [.1CA9.0020.0002]

चरण 3, प्रपत्र सॉर्ट कुंजियाँ:

è 1 => 1D10 0209 1CA4 0000 0020 0025 0020 0020 0000 0002 0002 0002 0002
ê 5 => 1D10 0209 1CA8 0000 0020 0027 0020 0020 0000 0002 0002 0002 0002
e 2 => 1D10 0209 1CA5 0000 0020 0020 0020 0000 0002 0002 0002
é 4 => 1D10 0209 1CA7 0000 0020 0024 0020 0020 0000 0002 0002 0002 0002
ē 3 => 1D10 0209 1CA6 0000 0020 0032 0020 0020 0000 0002 0002 0002 0002
ë 6 => 1D10 0209 1CA9 0000 0020 002B 0020 0020 0000 0002 0002 0002 0002

चरण 4, सॉर्ट कुंजी की तुलना करें:

मूल रूप से तीसरा मान आदेश को निर्धारित करता है, और यह वास्तव में केवल अंतिम अंक पर आधारित होता है, इसलिए आदेश होना चाहिए:

è 1
e 2
ē 3
é 4
ê 5
ë 6

दूसरा अद्यतन यूनिकोड संस्करणों के बारे में सोलोमन रुट्ज़की की टिप्पणी पर आधारित है।

मैंने allkeys.txtइस समय नवीनतम यूनिकोड संस्करण के बारे में डेटा का उपयोग किया , वह संस्करण 10.0 है

अगर हमें यूनिकोड 5.1 की जगह लेने की आवश्यकता है , तो यह होगा: http://www.unicode.org/Public/UCA/5.1.0/allkeys.txt

मैंने अभी जाँच की है, उपरोक्त सभी वर्णों के लिए, कोलाज सरणियाँ निम्नलिखित हैं:

e => [.119D.0020.0002.0065]
é => [.119D.0020.0002.0065] [.0000.0032.0002.0301]
ë => [.119D.0020.0002.0065] [.0000.0047.0002.0308]
è => [.119D.0020.0002.0065] [.0000.0035.0002.0300]
ê => [.119D.0020.0002.0065] [.0000.003C.0002.0302]
ē => [.119D.0020.0002.0065] [.0000.005B.0002.0304]

तथा:

eA => [.119D.0020.0002.0065] [.1141.0020.0008.0041]
éB => [.119D.0020.0002.0065] [.0000.0032.0002.0301] [.1157.0020.0008.0042]
ëC => [.119D.0020.0002.0065] [.0000.0047.0002.0308] [.116F.0020.0008.0043]
èD => [.119D.0020.0002.0065] [.0000.0035.0002.0300] [.1182.0020.0008.0044]
êE => [.119D.0020.0002.0065] [.0000.003C.0002.0302] [.119D.0020.0008.0045]
ēF => [.119D.0020.0002.0065] [.0000.005B.0002.0304] [.11D5.0020.0008.0046]

तथा:

è 1 => [.119D.0020.0002.0065] [.0000.0035.0002.0300] [*0209.0020.0002.0020] [.1138.0020.0002.0031]
ê 5 => [.119D.0020.0002.0065] [.0000.003C.0002.0302] [*0209.0020.0002.0020] [.113C.0020.0002.0035]
e 2 => [.119D.0020.0002.0065] [*0209.0020.0002.0020] [.1139.0020.0002.0032]
é 4 => [.119D.0020.0002.0065] [.0000.0032.0002.0301] [*0209.0020.0002.0020] [.113B.0020.0002.0034]
ē 3 => [.119D.0020.0002.0065] [.0000.005B.0002.0304] [*0209.0020.0002.0020] [.113A.0020.0002.0033]
ë 6 => [.119D.0020.0002.0065] [.0000.0047.0002.0308] [*0209.0020.0002.0020] [.113D.0020.0002.0036]

जो तब निम्न छँटाई कुंजी के लिए गणना:

e => 119D 0000 0020 0000 0002 0000 0065
é => 119D 0000 0020 0032 0000 0002 0002 0000 0065 0301
ë => 119D 0000 0020 0047 0000 0002 0002 0000 0065 0308
è => 119D 0000 0020 0035 0000 0002 0002 0000 0065 0300
ê => 119D 0000 0020 003C 0000 0002 0002 0000 0065 0302
ē => 119D 0000 0020 005B 0000 0002 0002 0000 0065 0304

तथा:

eA => 119D 1141 0000 0020 0020 0000 0002 0008 0000 0065 0041
éB => 119D 1157 0000 0020 0032 0020 0000 0002 0002 0008 0000 0065 0301 0042
ëC => 119D 116F 0000 0020 0047 0020 0000 0002 0002 0008 0000 0065 0308 0043
èD => 119D 1182 0000 0020 0035 0020 0000 0002 0002 0008 0000 0065 0300 0044
êE => 119D 119D 0000 0020 003C 0020 0000 0002 0002 0008 0000 0065 0302 0045
ēF => 119D 11D5 0000 0020 005B 0020 0000 0002 0002 0008 0000 0065 0304 0046

तथा:

è 1 => 119D 0209 1138 0000 0020 0035 0020 0020 0000 0002 0002 0002 0002 0000 0065 0300 0020 0031
ê 5 => 119D 0209 113C 0000 0020 003C 0020 0020 0000 0002 0002 0002 0002 0000 0065 0302 0020 0035
e 2 => 119D 0209 1139 0000 0020 0020 0020 0000 0002 0002 0002 0000 0065 0020 0032
é 4 => 119D 0209 113B 0000 0020 0032 0020 0020 0000 0002 0002 0002 0002 0000 0065 0301 0020 0034
ē 3 => 119D 0209 113A 0000 0020 005B 0020 0020 0000 0002 0002 0002 0002 0000 0065 0304 0020 0033
ë 6 => 119D 0209 113D 0000 0020 0047 0020 0020 0000 0002 0002 0002 0002 0000 0065 0308 0020 0036

जो फिर से इन तीन हल परिणामों को देता है:

e
é
è
ê
ë
ē

तथा

eA
éB
ëC
èD
êE
ēF

तथा

è 1
e 2
ē 3
é 4
ê 5
ë 6

हाय पैट्रिक। इस विस्तृत जानकारी को पोस्ट करने के लिए धन्यवाद। कुछ नोट: 1) आप कोड पृष्ठ 1252 को नजरअंदाज कर सकते हैं। यह VARCHAR(यानी गैर-यूनिकोड) डेटा के लिए है, जिसका उपयोग यहां नहीं किया गया है। यही कारण है कि ēचरित्र ठीक काम करता है। 2) "कॉलेशन-चार्ट" जानकारी थोड़ी पुरानी है। यह इस Collation के पिछले संस्करण के लिए है और उन्होंने 2009 के बाद से कुछ भी पोस्ट नहीं किया है। 3) यहां यूनिकोड संस्करण निश्चित रूप से नवीनतम (संस्करण 10) नहीं है। _100_श्रृंखला collations, एसक्यूएल 2008 के साथ आया था तो यह यूनिकोड 5.0 या 5.1 होगा: unicode.org/standard/versions/#TUS_Earlier_Versions
सोलोमन Rutzky

मुझे नहीं लगता कि allKeys.txt यूनिकोड संस्करण के अलावा, नए पात्रों के अलावा बदलाव, इसलिए उपरोक्त सही होना चाहिए, लेकिन निश्चित रूप से इसे पिछले पुराने डेटा के साथ फिर से जोड़ा जा सकता है, मुझे अभी इसमें कुछ घंटे फिर से लगाने की ऊर्जा की कमी है। CP1252 के रूप में यह सिर्फ MS-SQL द्वारा दी गई परिभाषा से आ रहा था (मैं स्वयं इस उत्पाद का उपयोग नहीं करता हूं)।
पैट्रिक मेवज़ेक

1) शायद संस्करणों के बीच बड़े बदलाव नहीं हैं, लेकिन मुझे पूरा यकीन है कि बहुत कम से कम वजन / वर्गीकरण सुधार हैं। लेकिन हां, मुझे निश्चित रूप से समय की कमी है;) 2) CP1252 के बारे में, मैं इसका उल्लेख कर रहा था क्योंकि कोड पेज की अवधारणा यूनिकोड के भीतर मौजूद नहीं है। यूनीकोड ​​कोड पेज की कभी जरूरत न होने का एक साधन है। एमएस डॉक इस पर स्पष्ट रूप से अस्पष्ट है, लेकिन यह शीर्ष " गैर-यूनिकोड चरित्र डेटा को संग्रहीत करने के लिए उपयोग किए जाने वाले कोड पृष्ठ " का उल्लेख करता है । आप सही हैं कि एक वर्ण CP1252 में नहीं है, लेकिन कोड पृष्ठ यहाँ खेलने में नहीं आते हैं।
सोलोमन रटज़की

हां, मैंने यूनिकोड से संबंधित कोड पृष्ठ के बारे में कभी कुछ नहीं कहा। यह सिर्फ MS SQL प्रलेखन है जो कहता है कि यह कोलाज नाम "कोड पृष्ठ 1252" के साथ काम करता है। इसका शायद कोई मतलब नहीं है (यह मेरे लिए नहीं है, लेकिन फिर, इसका एक उपयोगकर्ता नहीं है) लेकिन यह वही है जो इस सॉफ़्टवेयर के प्रलेखन में लिखा गया है। नौकरी को फिर से तैयार करने के लिए, ऐसा करने के लिए स्वतंत्र महसूस करें या केवल पात्रों के लिए संबंधित सॉर्टिंग के बारे में परिवर्तन प्रदान करें यहां यूनिकोड 5 और नवीनतम, यदि आप हैं और यदि आप चाहते हैं। मेरा मानना ​​है कि मेरा उत्तर स्टैंड जैसा है, सटीक है और इनपुट के आधार पर परिणाम बनाता है, अन्य तरीके से नहीं।
पैट्रिक मेवज़ेक

3) पुनः: वाक्य # 1: जबकि ज्यादातर यूनिकोड के बारे में, यह सवाल एक ओएस मुद्दा है क्योंकि एमएस ने कल्पना को लागू किया है और शायद यह सब नहीं किया है और / या कुछ गलतियां हो सकती हैं। मैंने .NET में 2 बग ढूंढे कि यह "श्रेणी" या "ब्लॉक" कैसे निर्धारित करता है कि एक विशेष चरित्र में है (वे वर्णों के एक छोटे खंड को गलत पहचान रहे थे)। इसके अलावा, इस है , कम से कम थोड़ा एक एसक्यूएल सर्वर मुद्दा है,, सिर्फ इसलिए कि एसक्यूएल सर्वर (संस्करणों के बीच स्थिरता के लिए) समय में एक बिंदु पर प्रभावी ढंग से प्रत्येक मिलान का एक स्नैपशॉट है, तो वे क्या अब एसक्यूएल सर्वर-विशिष्ट व्यवहार है हो सकता था।
सोलोमन रटज़की

16

यहां आप जो व्यवहार देख रहे हैं, वह एक सामान्य अर्थ में, इस तथ्य के कारण है कि यूनिकोड Collation Algorithm (UCA) जटिल, बहु-स्तरीय छँटाई के लिए अनुमति देता है। अधिक विशेष रूप से:

  1. छँटाई नहीं है तुलना:

    यह निर्धारित करना कि दो तार एक ही हैं या अलग-अलग काफी सीधे हैं (किसी विशेष स्थान / भाषा और संवेदनशीलता के सेट को देखते हुए)। लेकिन 2 या अधिक तारों के क्रम का निर्धारण अत्यधिक जटिल हो सकता है।

  2. छंटाई चरणों की एक श्रृंखला में की जाती है, प्रत्येक चरण को पूरे स्ट्रिंग पर लागू किया जाता है, चरित्र द्वारा नहीं:

    1. मानक: आधार वर्णों की तरह (उच्चारण और मामले के अंतर की परवाह किए बिना)
    2. अगर एक्सेंट-सेंसिटिव, उच्चारण / डायक्रिटिक वेट लागू करें
    3. यदि केस-संवेदी हो, तो केसिंग वेट लागू करें

जब आप col1(एकल वर्ण) द्वारा सॉर्ट करते हैं , तो यह पहले निर्धारित करता है कि सभी पात्रों का वजन समान है क्योंकि वे सभी " " हैं। इसके बाद, यह उच्चारण / डायक्रिटिक वज़न पर लागू होता है। कोई आवरण मतभेद नहीं हैं, इसलिए तीसरा चरण कुछ भी नहीं बदलेगा। तो चरण 2 में केवल अंतर हैं, यही वजह है कि उन पंक्तियों के आधार पर पसंदीदा ऑर्डर है col1

जब आप col2(दो वर्णों) को छाँटते हैं, तो यह पहले यह निर्धारित करता है कि प्रत्येक पंक्ति का अलग-अलग भार है क्योंकि दोनों वर्णों का उपयोग क्रमबद्ध भार (जैसे " ea ", " eb ", आदि) को निर्धारित करने के लिए किया जाता है । इसके बाद, यह उच्चारण / डायक्रिटिक वज़न पर लागू होता है। कोई आवरण मतभेद नहीं हैं, इसलिए तीसरा चरण कुछ भी नहीं बदलेगा। तो इस बार चरण 1 और 2 में अंतर हैं। लेकिन चूंकि चरण 2 में अंतर पहले से ही प्रत्येक स्ट्रिंग पर लागू हो चुके हैं, इससे पहले कि चरण 2 के वजन पर विचार किया जाता है, चरण 2 से भार का आदेश पर कोई प्रभाव नहीं पड़ता है; वे केवल तभी लागू होंगे जब दो या अधिक पंक्तियों के लिए चरण 1 से वज़न समान था।

प्रश्न से नमूना कोड का निम्नलिखित अनुकूलन उम्मीद है कि ऊपर वर्णित छँटाई व्यवहार को दिखाता है। मैंने कुछ अतिरिक्त पंक्तियों और एक अतिरिक्त कॉलम को जोड़ा, जो कि कोलाज के केस-संवेदी होने के प्रभाव को दिखाने में मदद करता है (क्योंकि मूल नमूना डेटा सभी लोअर-केस है):

सेट अप

USE [tempdb];

-- DROP TABLE dbo.OddSort;
CREATE TABLE dbo.OddSort
(
    id INT IDENTITY(1,1) PRIMARY KEY,
    col1 NVARCHAR(5) COLLATE Latin1_General_100_CS_AS,
    col2 NVARCHAR(5) COLLATE Latin1_General_100_CS_AS,
    col3 NVARCHAR(5) COLLATE Latin1_General_100_CS_AS
);
GO

INSERT dbo.OddSort (col1, col2, col3)
VALUES (N'e', N'eA', N'e A')
     , (N'ê', N'êE', N'ê E')
     , (N'é', N'éH', N'é H')
     , (N'ë', N'ëC', N'ë C')
     , (N'E', N'EG', N'E G')
     , (N'Ë', N'ëh', N'ë h')
     , (N'è', N'èD', N'è D')
     , (N'é', N'éB', N'é B')
     , (N'ë', N'ëH', N'ë H')
     , (N'ē', N'ēF', N'ē F');

परीक्षण १

SELECT [id], [col1], UNICODE([col1]) AS [CodePoint]
FROM dbo.OddSort 
ORDER BY col1;

यह दिखाता है:

id    col1    CodePoint
1     e       101
5     E       69
8     é       233
3     é       233
7     è       232
2     ê       234
4     ë       235
9     ë       235
6     Ë       203
10    ē       275

उपरोक्त परिणामों में हम क्या देख सकते हैं:

  1. कोड प्वाइंट सॉर्ट क्रम का निर्धारण नहीं कर रहा है
  2. गैर-उच्चारण वर्णों को उच्चारण वर्णों से पहले क्रमबद्ध किया जाता है (एक ही अक्षर के भीतर: f अभी भी इन सभी के बाद आएगा)। स्पष्ट रूप से, केस वेट से पहले उच्चारण भार लागू होते हैं।
  3. एक ही उच्चारण चिह्न (या गैर स्वराघात) चरित्र के भीतर अपर-केस (यानी पहले लोअर केस प्रकार तो , और ë तो )। इस टेलरिंग का उपयोग अधिकांश Windows Collations द्वारा किया जाता है, जबकि अधिकांश SQL सर्वर Collations ऊपरी-केस को पहले सॉर्ट करते हैं।

परीक्षण २

SELECT [id], [col2]
FROM dbo.OddSort 
ORDER BY col2;

यह दिखाता है:

id    col2
1     eA
8     éB
4     ëC
7     èD
2     êE
10    ēF
5     EG
3     éH
6     ëh
9     ëH

उपरोक्त परिणामों में हम क्या देख सकते हैं:

  1. प्रथम-स्तरीय सॉर्टिंग वास्तव में आधार वर्ण है। यदि यह लहजे / diacritics थे, तो ëC (id = 4), accF (id = 10), और EG (id = 5) पंक्तियाँ ऐसी नहीं होंगी जहाँ वे हैं। यदि यह आवरण होता, तो ईजी (आईडी = 5) पंक्ति वह नहीं होती जहां यह है।
  2. दूसरे स्तर पर सही मायने में लहजे / diacritics है। यह बताता है कि अंतिम तीन पंक्तियाँ éH -> ëh -> ëH की जगह ëh -> éH -> ëH (यानी IDs 3 -> 6 -> 9 के बजाय 6 -> 3 -> 9) क्यों होती हैं।
  3. तीसरे स्तर की छँटाई वास्तव में आवरण है। यही कारण है कि अंतिम 2 पंक्तियाँ ëh -> ëH होती हैं , क्योंकि निचले-मामले पहले होते हैं।

परीक्षण ३

SELECT [id], [col3]
FROM dbo.OddSort 
ORDER BY col3;

यह दिखाता है:

id    col3
1     e A
8     é B
4     ë C
7     è D
2     ê E
10    ē F
5     E G
3     é H
6     ë h
9     ë H

उपरोक्त परिणामों में हम क्या देख सकते हैं:

  1. सॉर्ट ऑर्डर टेस्ट 2 की तरह ही है। यहां टेस्ट वैल्यू में एकमात्र अंतर यह है कि प्रत्येक चरित्र के बीच एक स्थान होता है, जो प्रासंगिक नियमों की संभावना को दूर करता है। इसलिए, हम जानते हैं कि col2प्रश्न के लिए क्रमबद्ध क्रम में अंतर का कारण फिर से "मल्टी-लेवल कम्पेरिसन" है, न कि "कॉन्सेक्चुअल सेंसिटिविटी"।

अतिरिक्त नोट्स:

  1. सटीक नियम प्राप्त करने के संबंध में, यह उतना आसान नहीं है जितना कि होना चाहिए। इन नियमों के ठोस स्पष्टीकरण के साथ समस्या यह है कि यूनिकोड छँटाई के नियम, जबकि निश्चित रूप से प्रलेखित हैं, एक सिफारिश है। यह उन सिफारिशों को लागू करने के लिए Microsoft जैसे विक्रेताओं पर निर्भर है। Microsoft ने यूनिकोड दस्तावेज में बताई गई सिफारिशों को ठीक से लागू नहीं किया है, इसलिए वहां एक डिस्कनेक्ट है (इसी तरह न तो HTML या सीएसएस विनिर्देशों को पूरी तरह से लागू किया जाता है, और न ही उसी तरह, विक्रेताओं के पार भी)। उसके बाद, Windows Collations के विभिन्न संस्करण हैं (आप 100SQL सर्वर 2008 के साथ आए संस्करण का उपयोग कर रहे हैं ) और यह एक यूनिकोड संस्करण से बंधा है जो यूनिकोड के वर्तमान संस्करण की तुलना में बहुत पुराना है या ICU Collation डेमोउपयोग कर रहा है। उदाहरण के लिए,SQL Server 2008 में नया क्या है "Collation and Unicode Support" दस्तावेज़ीकरण अनुभाग SQL Server 2008 के लिए दस्तावेज़ीकरण_100_ श्रृंखला कोलेशन के लिए "नया" क्या है, इसके बारे में 2 बहुत ही रोचक बाते बताती है:

    1. यूनिकोड 5.0 केस टेबल।

      यूनिकोड 5.0 को 2006 के जुलाई में प्रकाशित किया गया था (ठीक है, चरित्र डेटाबेस तब जारी किया गया था, और 2006 के अंत में पूर्ण कल्पना का अनुसरण किया गया था)। वर्तमान संस्करण 10.0 है जो 2017 के जून में प्रकाशित हुआ था। और पिछले 4 वर्षों के रिलीज पैटर्न को देखते हुए, यह संभावना है कि संस्करण 11.0 2018 के मध्य से बाहर हो जाएगा।

    2. वेटिंग को पहले के गैर-वेटेड पात्रों में जोड़ा गया है, जो समान रूप से तुलना करेंगे।

      उन वज़न यूनिकोड मानक में परिभाषित होने की तुलना में अधिक थे, बस इसके कार्यान्वयन में नहीं।

     
    फिर भी, ऊपर जुड़ा यूसीए प्रलेखन शुरू करने के लिए एक अच्छी जगह है।

  2. विंडोज / .NET / SQL सर्वर द्वारा उपयोग की जाने वाली सॉर्ट कीज यूनिकोड स्टैंडर्ड (@ पैट्रिक का जवाब देखें) या ICU में लागू किए गए के समान नहीं हैं । विंडोज / .NET / SQL सर्वर का उपयोग करने के लिए, आप तुलना करें InInfo.GetSortKey विधि का उपयोग कर सकते हैं । मैंने इन मानों को पास करने और सॉर्ट कुंजी प्राप्त करने के लिए SQLCLR UDF बनाया। कृपया ध्यान दें कि मैं .NET फ्रेमवर्क 4.5 - 4.6.1 स्थापित के साथ विंडोज 10 पर एसक्यूएल सर्वर 2017 का उपयोग कर रहा हूं, इसलिए .NET को यूनिकोड 6.0.0 का उपयोग करना चाहिए। साथ ही, इन स्ट्रिंग्स के लिए Level4 का उपयोग नहीं किया जा रहा है।

    CHAR    L1     L2     L3     L4
    e      0E21
    E      0E21           12
    ë      0E21    13
    Ë      0E21    13     12

    टेस्ट 1 के लिए इन प्रकार की कुंजियों को देखते हुए, और यह महसूस करते हुए कि स्तरों को एक स्तंभ के भीतर कई स्तंभों की तरह क्रमबद्ध किया जाता ORDER BYहै (L3 L2 के समान मूल्यों के भीतर क्रमबद्ध होता है, जो L1 के समान मूल्यों के भीतर क्रमबद्ध होता है), यह वर्णन करना चाहिए कि व्यवहार का कारण सवाल में कहा गया है वास्तव में यूनिकोड की बहु-स्तरीय छँटाई क्षमता है। इसी तरह:

    CHAR       L1         L2       L3       L4
    EG      0E210E25              1212
    éH      0E210E2C      0E      0212
    ëh      0E210E2C      13
    ëH      0E210E2C      13      0212

    टेस्ट 2 के लिए कुछ प्रकार की कुंजियों को देखते हुए, हम देख सकते हैं कि आधार वर्ण पहले (L1) क्रमबद्ध किए जाते हैं, फिर लहजे को क्रमबद्ध (L2), और फिर आवरण को क्रमबद्ध (L3) किया जाता है।

  3. चूंकि डेटाटाइप है NVARCHAR, हम केवल यूनिकोड कोड पॉइंट्स और सॉर्टिंग एल्गोरिदम के साथ चिंतित हैं, इसलिए UNICODE()टेस्ट 1 में फ़ंक्शन का उपयोग । जबकि अधिकांश कॉलेशन द्वारा कोड पेज निर्दिष्ट किए गए हैं, वे केवल VARCHARडेटा से संबंधित हैं । मतलब, जबकि कोड पृष्ठ 1252 Latin1_General*कोलेशन की श्रृंखला द्वारा निर्दिष्ट किया गया है , जिसे यहां अनदेखा किया जा सकता है।

  4. डिफ़ॉल्ट यूनिकोड Collation Element Table (DUCET) ( संस्करण 5.0.0 जो _100_श्रृंखला Collations के लिए मैप करना चाहिए ) में वर्णित वज़न US अंग्रेजी के लिए ठीक है, लेकिन अन्य स्थानों / भाषाओं के लिए नहीं। अन्य भाषाओं को DUCET से शुरू करने और फिर कॉमन लोकेल डेटा रिपॉजिटरी (सीएलडीआर) परियोजना द्वारा परिभाषित स्थानीय-विशिष्ट ओवरराइड नियमों को लागू करने की आवश्यकता है । मैं जो बता सकता हूं, उससे 2006 में संस्करण 1.4 / 1.4.1 जारी किए गए थे। उन ओवरराइड्स को प्राप्त करने के लिए, http://unicode.org/Public/cldr/1.4.0/core.zip के माध्यम से CLDR 1.4 "कोर" फ़ाइल डाउनलोड करें। , फिर उस ज़िप फ़ाइल में, कॉलेशन फोल्डर में जाएँ और एक्सएमएल फ़ाइल को उसी लोकेल के अनुसार खोजें। उन फ़ाइलों में बस ओवरराइड होते हैं, और कोलाजेशन नियमों के पूर्ण सेट नहीं होते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.