<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>SQL Programmability &amp; API Development Team Blog : Sorting</title><link>http://blogs.msdn.com/sqlprogrammability/archive/tags/Sorting/default.aspx</link><description>Tags: Sorting</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>How are GUIDs compared in SQL Server 2005?</title><link>http://blogs.msdn.com/sqlprogrammability/archive/2006/11/06/how-are-guids-compared-in-sql-server-2005.aspx</link><pubDate>Tue, 07 Nov 2006 01:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1006101</guid><dc:creator>mathh</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/sqlprogrammability/comments/1006101.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqlprogrammability/commentrss.aspx?PostID=1006101</wfw:commentRss><description>&lt;P&gt;In general, equality comparisons make a lot of sense with uniqueidentifier values. However, if you find yourself needing general ordering, then you might be looking at the wrong data type and should consider various integer types instead.&lt;/P&gt;
&lt;P mce_keep="true"&gt;If, after careful thought, you decide to order on a uniqueidentifier column, you might be surprised by what you get back.&lt;/P&gt;
&lt;P&gt;Given these two uniqueidentifier values:&lt;/P&gt;
&lt;P&gt;@g1=&amp;nbsp;'55666BEE-B3A0-4BF5-81A7-86FF976E763F'&lt;BR&gt;@g2 =&amp;nbsp; '8DD5BCA5-6ABE-4F73-B4B7-393AE6BBB849'&lt;/P&gt;
&lt;P&gt;Many people think that @g1 is less than @g2, since '55666BEE' is certainly smaller than '8DD5BCA5'. However, this is not how SQL Server 2005 compares uniqueidentifier values. &lt;/P&gt;
&lt;P&gt;The comparison is made by looking at byte "groups" right-to-left, and left-to-right within a byte "group". A byte group is what is delimited by the '-' character. More technically, we look at bytes {10 to 15} first, then {8-9}, then {6-7}, then {4-5}, and lastly {0 to 3}.&lt;/P&gt;
&lt;P&gt;In this specific example, we would start by comparing '86FF976E763F' with '393AE6BBB849'. Immediately we see that @g2 is indeed greater than @g1.&lt;/P&gt;
&lt;P&gt;Note that in .NET languages, &lt;A class="" href="http://msdn2.microsoft.com/en-us/library/system.guid(VS.80).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.guid(VS.80).aspx"&gt;Guid&lt;/A&gt; values have a different default sort order than in SQL Server. If you find the need to order an array or list of Guid using SQL Server comparison semantics, you can use an array or list of &lt;A class="" href="http://msdn2.microsoft.com/en-us/library/system.data.sqltypes.sqlguid(VS.80).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.data.sqltypes.sqlguid(VS.80).aspx"&gt;SqlGuid&lt;/A&gt;&amp;nbsp;instead, which implements IComparable in a way which is consistent with SQL Server semantics. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1006101" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/Sorting/default.aspx">Sorting</category><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/Native+Types+and+Methods/default.aspx">Native Types and Methods</category></item><item><title>Sorting undefined characters in Unicode and/or Windows collation</title><link>http://blogs.msdn.com/sqlprogrammability/archive/2006/04/07/570397.aspx</link><pubDate>Fri, 07 Apr 2006 02:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:570397</guid><dc:creator>Jun Fang</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/sqlprogrammability/comments/570397.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqlprogrammability/commentrss.aspx?PostID=570397</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;When comparing two Unicode strings in non-binary collations, SQL Server uses a library that is essentially same as the Windows API CompareStringW. It defines a weight for each recognized character, and then use the weights to compare characters. However, not all code points are defined in the sorting library. They may be undefined because:&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;1) The code point is not defined in Unicode standard.&lt;BR&gt;2) The code point is defined in Unicode standard, but not defined by Windows yet. It takes time and effort to define linguistic sorting semantics for new characters. Windows team typically needs to work with local standard body and/or regional PMs to define sorting rules for new characters. They add new character support in every release, and try to catch up. Some characters may have font defined, therefore could be correctly displayed, but still not defined in terms of comparison. For example, NCHAR(13144) - NCHAR(13174).&lt;BR&gt;3) The code point is defined in Windows, but not defined in SQL Server yet. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;Windows NLS team has decided that undefined characters are ignored during string comparison, partly because there is no real good way to compare them against other defined characters. SQL Server inherited this semantics. This does cause some confusing behavior.&amp;nbsp;See below examples.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;declare @undefined_char1 nvarchar(10), @undefined_char2 nvarchar(10)&lt;BR&gt;set @undefined_char1 = nchar(0x0000)&lt;BR&gt;set @undefined_char2 = nchar(13144)&lt;BR&gt;select 'Undefine characters compare equal to empty string'&lt;BR&gt;where @undefined_char1 = ''&lt;BR&gt;select 'All undefine characters compare equal'&lt;BR&gt;where @undefined_char1 = @undefined_char2&lt;BR&gt;go&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;create table t (c nvarchar(10))&lt;BR&gt;go&lt;BR&gt;create unique index it on t(c)&lt;BR&gt;go&lt;BR&gt;-- first insert succeeds, but second insert fails with duplicate key error.&lt;BR&gt;insert t values (nchar(0x0000))&lt;BR&gt;insert t values (nchar(13144))&lt;BR&gt;go&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;As you can see, since all undefined characters compare equal, they could cause duplicate key errors. Similarly, if you create one table with name of an undefined character, and then try to create another table with another undefined character, the second table creation would fail due to duplicate names, even though the code points of the two undefined characters are different. This could also cause confusing results in string matching builtins such as CHARINDEX, PATINDEX, or LIKE.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;While these results seem confusing, the basic rule is actually very simple, i.e., undefined characters are ignored during comparison and string matching. Once you understand and remember this rule, the behavior should be easy to understand. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;There have been arguments whether undefined characters should be ignored. Since this is the behavior on Windows platform, and there is not a definitely better way to sort them, and for backwards compatibility, we are going to maintain this behavior. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;If your app needs to work with these undefined characters and expect to treat them as regular characters, you can use binary collation. In binary collation, comparison is done purely based on code points, not linguistic rules, so there is no notion about defined vs. undefined.&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=570397" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/Sorting/default.aspx">Sorting</category><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+Server+2000/default.aspx">SQL Server 2000</category><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/Native+Types+and+Methods/default.aspx">Native Types and Methods</category></item></channel></rss>