Swego czasu popełniłem na blogu wpis poświęcony collation i najlepszym praktykom dla programistów właśnie w kontekście wyboru i wykorzystywania różnych collation. Ostatnio jedna z odwiedzających mojego bloga osób – pseudonim robert (credits!) – zwróciła mi uwagę, że jeden z przykładów w tamtym wpisie jest (cyt.) “bałamutny” :-)

Przykład dotyczył sortowania wartości tekstowych zapisanych w “długich” i “krótkich” collation, w których występowały myślniki. Faktycznie, jeżeli rozbudujemy ów przykład, to okazuje się, że w żadnym z dwóch użytych collation sortowanie nie jest doskonałe (czyt. zgodne z oczekiwaniami):

SELECT *
FROM (
  VALUES ('a'), ('a-'), ('a-a'), ('a-b'), ('aa'), ('ab'), ('aa-')
) AS T(c)
ORDER BY c COLLATE SQL_Polish_CP1250_CS_AS;
GO
SELECT *
FROM (
  VALUES ('a'), ('a-'), ('a-a'), ('a-b'), ('aa'), ('ab'), ('aa-')
) AS T(c)
ORDER BY c COLLATE Polish_CI_AS;
GO

Wynik wykonania powyższych zapytań:

image

Wynik sortowania w przypadku collation SQL_Polish_CP1250_CS_AS jest zły, ponieważ wartość ‘a’, której spodziewałbym się na początku posortowanego zbioru, jest nie na swojej pozycji (4).

Ale wynik drugiego zapytania też nie jest poprawny z punktu widzenia tego, jak powinno zadziałać sortowanie. Wartość ‘a-‘ znajduje się przed wartością ‘aa’ (i to jest zgodne z moim oczekiwaniem), ale z kolei wartość ‘aa’ jest przed wartością ‘a-a‘. I w tym momencie już wynik sortowania jest niespójny – raz mamy symbol ‘-‘ przed symbolem ‘a’, a innym razem jest na odwrót.

Ciekawe, że najlepiej w tych “zawodach w sortowaniu” wypada collation binarne:

SELECT *
FROM (
  VALUES ('a'), ('a-'), ('a-a'), ('a-b'), ('aa'), ('ab'), ('aa-')
) AS T(c)
ORDER BY c COLLATE Polish_BIN;
GO

Wynik takiego sortowania:

image

Wygląda poprawnie. Nie oznacza to, że używałbym collation Polish_BIN, ale w tym wypadku wypadło ono najlepiej (może do ew. sortowań z udziałem wartości z myślnikami czasem dobrze mieć kolumnę wyliczaną z collation binarnym?).

Powyższe testy wykonałem na SQL Server 2012 (build 11.0.3368).

Są rzeczy o których nie śniło się geekom SQL-owym ;-) A może ktoś z Was potrafi rozszyfrować przyczyny takiego stanu rzeczy? Może ja gdzieś zbłądziłem… Z góry dziękuję za wszelkie sugestie :-)