Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Сортировка по uniqueidentifier  [new]
Prolog
Member

Откуда: Москва
Сообщений: 2791
set nocount on;
declare @t table (guid uniqueidentifier primary key); insert @t values
('048B9E9E-6FE3-E811-B806-0050568515CC'),
('26E3B539-F0E3-E811-B806-0050568515CC'),
('39F7D4F1-58E3-E811-B806-0050568515CC'),
('4516A640-F0E3-E811-B806-0050568515CC'),
('6C424612-81E2-E811-B806-0050568515CC'),
('924C2CA1-D2E1-E811-B806-0050568515CC'),
('93A5975D-6FE3-E811-B806-0050568515CC'),
('978D2B02-71E3-E811-B806-0050568515CC'),
('C226932A-25E3-E811-B806-0050568515CC'),
('F5E5DB35-71E3-E811-B806-0050568515CC');

-- 1й запрос
select guid,hex=convert(binary(16),guid) from @t order by guid asc;

-- 2й запрос
with s as(select rn=row_number() over(order by guid asc),guid,hex=convert(binary(16),guid) from @t)
select
  s1.*,
  case when s1.hex>s2.hex then '>' when s1.hex<s2.hex then '<' else '' end
 from
  s s1 left join s s2 on s2.rn=s1.rn-1
 order by
   s1.guid asc;

rnguidhexсравнение
1924C2CA1-D2E1-E811-B806-0050568515CC0xA12C4C92E1D211E8B8060050568515CC
26C424612-81E2-E811-B806-0050568515CC0x1246426CE28111E8B8060050568515CC<
3C226932A-25E3-E811-B806-0050568515CC0x2A9326C2E32511E8B8060050568515CC>
439F7D4F1-58E3-E811-B806-0050568515CC0xF1D4F739E35811E8B8060050568515CC>
593A5975D-6FE3-E811-B806-0050568515CC0x5D97A593E36F11E8B8060050568515CC<
6048B9E9E-6FE3-E811-B806-0050568515CC0x9E9E8B04E36F11E8B8060050568515CC>
7978D2B02-71E3-E811-B806-0050568515CC0x022B8D97E37111E8B8060050568515CC<
8F5E5DB35-71E3-E811-B806-0050568515CC0x35DBE5F5E37111E8B8060050568515CC>
926E3B539-F0E3-E811-B806-0050568515CC0x39B5E326E3F011E8B8060050568515CC>
104516A640-F0E3-E811-B806-0050568515CC0x40A61645E3F011E8B8060050568515CC>


Приведён результат 2го запроса, так как результат 1го запроса есть столбцы guid, hex 2го запроса в той же последовательности.
Оба запроса сортируют результат по возрастанию столбца guid. Но, как видно, сортировка есть строки значение которых меньше, чем у предыдущей строки.

Если отсортировать по столбцу hex:
with s as(select rn=row_number() over(order by convert(binary(16),guid) asc),guid,hex=convert(binary(16),guid) from @t)
select
  s1.*,
  case when s1.hex>s2.hex then '>' when s1.hex<s2.hex then '<' else '' end
 from
  s s1 left join s s2 on s2.rn=s1.rn-1
 order by
   s1.hex asc;

, то получим правильный порядок строк по столбцу hex, но опять-таки - непонятный порядок по столбцу quid:

rnguidhexсравнение
1978D2B02-71E3-E811-B806-0050568515CC0x022B8D97E37111E8B8060050568515CC
26C424612-81E2-E811-B806-0050568515CC0x1246426CE28111E8B8060050568515CC>
3C226932A-25E3-E811-B806-0050568515CC0x2A9326C2E32511E8B8060050568515CC>
4F5E5DB35-71E3-E811-B806-0050568515CC0x35DBE5F5E37111E8B8060050568515CC>
526E3B539-F0E3-E811-B806-0050568515CC0x39B5E326E3F011E8B8060050568515CC>
64516A640-F0E3-E811-B806-0050568515CC0x40A61645E3F011E8B8060050568515CC>
793A5975D-6FE3-E811-B806-0050568515CC0x5D97A593E36F11E8B8060050568515CC>
8048B9E9E-6FE3-E811-B806-0050568515CC0x9E9E8B04E36F11E8B8060050568515CC>
9924C2CA1-D2E1-E811-B806-0050568515CC0xA12C4C92E1D211E8B8060050568515CC>
1039F7D4F1-58E3-E811-B806-0050568515CC0xF1D4F739E35811E8B8060050568515CC>


Если конвертировать guid в varchar отсортировать по этому значению:
with s as(select rn=row_number() over(order by convert(varchar(36),guid) asc),guid=convert(varchar(36),guid),hex=convert(binary(16),guid) from @t)
select
  s1.*,
  'сравнение'=case when s1.guid>s2.guid then '>' when s1.guid<s2.guid then '<' else '' end
 from
  s s1 left join s s2 on s2.rn=s1.rn-1
 order by
   s1.guid;

, то получим правильную сортировку сортировку по quid, но неправильную по hex:

rnguidhexсравнение
1048B9E9E-6FE3-E811-B806-0050568515CC0x9E9E8B04E36F11E8B8060050568515CC
226E3B539-F0E3-E811-B806-0050568515CC0x39B5E326E3F011E8B8060050568515CC>
339F7D4F1-58E3-E811-B806-0050568515CC0xF1D4F739E35811E8B8060050568515CC>
44516A640-F0E3-E811-B806-0050568515CC0x40A61645E3F011E8B8060050568515CC>
56C424612-81E2-E811-B806-0050568515CC0x1246426CE28111E8B8060050568515CC>
6924C2CA1-D2E1-E811-B806-0050568515CC0xA12C4C92E1D211E8B8060050568515CC>
793A5975D-6FE3-E811-B806-0050568515CC0x5D97A593E36F11E8B8060050568515CC>
8978D2B02-71E3-E811-B806-0050568515CC0x022B8D97E37111E8B8060050568515CC>
9C226932A-25E3-E811-B806-0050568515CC0x2A9326C2E32511E8B8060050568515CC>
10F5E5DB35-71E3-E811-B806-0050568515CC0x35DBE5F5E37111E8B8060050568515CC>


Это какая-то особенность типа uniqueidentifier: последовательность возрастания значений во внутреннем представлении uniqueidentifier не совпадает с последовательностью возрастания представления значений этого типа в символьном или бинарном виде? Как-то хотелось бы при сортировке по столбцу uniqueidentifier (по которому ещё и построен индекс) видеть глазами ожидаемый результат: строки идут по возрастанию. Не хотелось бы ещё делать конвертацию в другие типы и строить по ним ещё один индекс.

Вот ещё один неприятный момент, когда "визуальное" представление о том, что больше-меньше, не совпадает с тем, что получается в итоге:
print case when                          0xA12C4C92E1D211E8B8060050568515CC      >                          0x1246426CE28111E8B8060050568515CC      then 1 else 0 end;
print case when convert(uniqueidentifier,0xA12C4C92E1D211E8B8060050568515CC)     > convert(uniqueidentifier,0x1246426CE28111E8B8060050568515CC)     then 1 else 0 end;
print case when                          '924C2CA1-D2E1-E811-B806-0050568515CC'  >                          '6C424612-81E2-E811-B806-0050568515CC'  then 1 else 0 end;
print case when convert(uniqueidentifier,'924C2CA1-D2E1-E811-B806-0050568515CC') > convert(uniqueidentifier,'6C424612-81E2-E811-B806-0050568515CC') then 1 else 0 end;

-- результат:
-- 1
-- 0
-- 1
-- 0
10 июл 19, 14:49    [21924221]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка по uniqueidentifier  [new]
Konst_One
Member

Откуда:
Сообщений: 11335
https://docs.microsoft.com/ru-ru/sql/t-sql/functions/newsequentialid-transact-sql?view=sql-server-2017
10 июл 19, 14:53    [21924227]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка по uniqueidentifier  [new]
aleks222
Member

Откуда:
Сообщений: 696
guid не предназначен для "сортировки"

Prolog
Это какая-то особенность типа uniqueidentifier: последовательность возрастания значений во внутреннем представлении uniqueidentifier не совпадает с последовательностью возрастания представления значений этого типа в символьном или бинарном виде?


Ты ниповеришь!
Даже для int все очень печально.
В этом смысле.
Да шо там int, varchar туда же.
10 июл 19, 14:57    [21924230]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка по uniqueidentifier  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36278
Невооруженным глазом видно, что в текстовом представлении в некоторых секциях байты стоят в обратном порядке.
Возможно, связано с особенностью хранения структуры в памяти.
10 июл 19, 15:00    [21924233]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка по uniqueidentifier  [new]
Prolog
Member

Откуда: Москва
Сообщений: 2791
Konst_One,

Самое интересное, что такое свойство как раз обнаружилось на столбце с NEWSEQUENTIALID().
10 июл 19, 15:26    [21924243]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка по uniqueidentifier  [new]
Konst_One
Member

Откуда:
Сообщений: 11335
вы уверены, из вашего кода этого не видно. было бы неплохо иметь дополнительное поле времени вставки записи в вашей таблице, чтобы его использоввать в сортировке
10 июл 19, 15:36    [21924248]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка по uniqueidentifier  [new]
invm
Member

Откуда: Москва
Сообщений: 8664
Prolog,

https://blogs.msdn.microsoft.com/sqlprogrammability/2006/11/06/how-are-guids-compared-in-sql-server-2005/
10 июл 19, 15:50    [21924264]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка по uniqueidentifier  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6378
т.е. что то guid сортировки нет, и монотонного возрастания тоже нет, то давайте в что нибудь сконвертируем и вдруг...
10 июл 19, 16:05    [21924268]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка по uniqueidentifier  [new]
Prolog
Member

Откуда: Москва
Сообщений: 2791
invm,

Спасибо, теперь хотя принцип понятен, как сравнивается uniqueidentifier.
10 июл 19, 16:35    [21924297]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить