Поле сортировки строк, которое содержит целые числа, десятичные дроби и строки SQL - PullRequest
1 голос
/ 28 января 2020

Я унаследовал проект, в котором есть таблица, которая может содержать строку, десятичное число или целое число.

Мне нужно отсортировать по этому полю.

Предположим, что я могу (основываясь на идентификатор) захватывать только один тип за один раз, но, чтобы быть уверенным, я все еще хочу подтвердить тип перед сортировкой, и если это не тот же тип, просто отсортировать по строке.

Таким образом, таблица может выглядеть так.

select id, fkID, myValue from myTable

 id |fkID|myValue
____|____|_______
 1  |14  |abc
 2  |14  |ghi
 3  |14  |def

 4  |11  |2000
 5  |11  |1500
 6  |11  |10000

 7  |17  |110.04
 8  |17  |500.22
 9  |17  |100.99

Тогда скажите, что я могу получить все fkID 11. Я бы хотел, чтобы это было отсортировано

 5  |11  |1500
 4  |11  |2000
 6  |11  |10000

Или fkID 14 будет

 1  |14  |abc
 3  |14  |def
 2  |14  |ghi

Я не могу понять, как решить эту проблему, но попытался использовать Try_Parse для определения значения столбца.

Dynami c sql хорошо, если это то, что работает.

Ответы [ 2 ]

1 голос
/ 28 января 2020

Похоже, что вы унаследовали структуру, которая плохо обрабатывается на sql -сервере или в любой крупной базе данных (напоминает мне о чрезмерно нормализованных шаблонах EAV и OTLT).

Вы можете:

  1. Используйте try_convert для захвата десятичных представлений, если они доступны.
  2. Используйте оконный максимум, чтобы определить, есть ли не десятичные числа.
  3. Используйте условный оператор, используя разные версии row_number для получения вашего заказа.

Вот оно в действии:

declare @fkId int = 11;

select      t.*,
            ord = iif( 
                max(iif(decVal is null, 1, 0)) over() = 1, -- has any non decimals?
                row_number() over(order by myValue), -- string ordering
                row_number() over(order by decVal) -- decimal ordering
            )
from        @myTable t
cross apply (select decVal = try_convert(decimal(10,2), myValue)) ap
where       fkId = @fkId -- replace this with whatever.
order by    ord;
0 голосов
/ 28 января 2020

Это отвечает оригинальной версии вопроса.

Для ваших примеров вы просто должны использовать:

order by my_value

Указанный вами порядок - даже для чисел - работает с алфавитным порядком.

...