TSQL - можно ли определить порядок сортировки? - PullRequest
23 голосов
/ 25 января 2011

Можно ли определить порядок сортировки для возвращаемых результатов?

Я бы хотел, чтобы порядок сортировки был «апельсиновый», «яблочный», «клубничный», а не восходящий или нисходящий.

Я знаю, что ORDER BY может выполнять ASC или DESC, но есть ли вещи типа DEFINED («апельсин», «яблоко», «клубника»)?

Это будет работать на SQL Server 2000.

Ответы [ 7 ]

51 голосов
/ 25 января 2011

Это невероятно неуклюже, но вы можете использовать оператор CASE для упорядочения:

SELECT * FROM Blah 
ORDER BY CASE MyColumn 
    WHEN 'orange' THEN 1 
    WHEN 'apple' THEN 2 
    WHEN 'strawberry' THEN 3 
    END 

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

TargetValue  SortOrder
orange       1
apple        2
strawberry   3

И присоедините ваш стол к этому новому столу.

11 голосов
/ 25 января 2011

Использовать оператор CASE :

ORDER BY CASE your_col
           WHEN 'orange' THEN 1
           WHEN 'apple' THEN 2
           WHEN 'strawberry' THEN 3
         END 

Альтернативный синтаксис с ELSE:

ORDER BY CASE 
           WHEN your_col = 'orange' THEN 1
           WHEN your_col = 'apple' THEN 2
           WHEN your_col = 'strawberry' THEN 3
           ELSE 4
         END 
7 голосов
/ 25 января 2011

Если это будет недолгим требованием, используйте оператор case. Однако, если вы думаете, что это может быть какое-то время, и это всегда будет порядка orange/apple/strawberry (или даже если нет - см. Ниже), вы можете подумать о том, чтобы пожертвовать некоторым дисковым пространством, чтобы получить некоторую скорость.

Создайте в вашей таблице новый столбец с именем or_ap_st и используйте триггер вставки / обновления, чтобы заполнить его числами 1, 2 или 3, в зависимости от значения вашего столбца фруктов. Тогда индекс на это.

Поскольку данные в этом столбце изменяются только при изменении строки, это лучшее время для этого. Затем стоимость будет понесена при небольшом количестве операций записи, а не при большом количестве операций чтения, следовательно, амортизируется по операторам select.

Ваш запрос будет невероятно быстрым:

select field1, field2 from table1
order by or_ap_st;

без функций для каждой строки, убивающих производительность.

И, если вам нужны и другие порядки сортировки, вот почему я назвал столбец or_ap_st. Вы можете добавить столько столбцов сортировки, сколько вам нужно.

2 голосов
/ 25 января 2011

В этом случае я делаю

ORDER BY
  CASE WHEN FRUIT = 'Orange' THEN 'A' 
       WHEN FRUIT = 'Apple' THEN 'B'
       WHEN FRUIT = 'Strawberry' THEN 'C'
       ELSE FRUIT
END
1 голос
/ 22 июля 2016

Переход от ответа turtlepick :

ORDER BY
  CASE WHEN FRUIT = 'Orange' THEN 'A' 
       WHEN FRUIT = 'Apple' THEN 'B'
       WHEN FRUIT = 'Strawberry' THEN 'C'
       ELSE FRUIT
  END

Если у вас есть еще несколько элементов во ФРУКТЕ, и они начинаются с букв, определенных после ТОГДА ключевых слов, эти элементы будут отображатьсяжестко закодированный заказ.Например, банан появляется перед клубникой.Вы можете обойти это с помощью

ORDER BY
  CASE
    WHEN FRUIT = 'Orange' THEN '.1'
    WHEN FRUIT = 'Apple' THEN '.2'
    WHEN FRUIT = 'Strawberry' THEN '.3'
    ELSE FRUIT
  END

Здесь я использовал символы с более низкими значениями ASCII в надежде, что они не появятся в начале значений в FRUIT.

0 голосов
/ 19 января 2018

Не так часто, но для операций с одним значением или определенных шаблонов, ЗАМЕНА тоже работает

например.

DECLARE @Fruit TABLE (Fruit_Id INT IDENTITY(1, 1) PRIMARY KEY ,Name VARCHAR(50));

INSERT  INTO @Fruit (Name) VALUES  ('Orange');
INSERT  INTO @Fruit (Name) VALUES  ('Apple');
INSERT  INTO @Fruit (Name) VALUES  ('Strawberry');
INSERT  INTO @Fruit (Name) VALUES  ('__Pear');


SELECT * FROM @Fruit AS f
ORDER BY REPLACE(f.Name,'__','')



Fruit_Id    Name
----------- --------------------------------------------------
2           Apple
1           Orange
4           __Pear
3           Strawberry
0 голосов
/ 06 декабря 2017

Добавьте ключ к таблице (например, первичный ключ fruit_id int identity (1,1)), чтобы сохранить порядок вставки

create table fruit(fruit_id int identity(1,1) primary key, name varchar(50))
go

insert into fruit(name) values ('orange')
insert into fruit(name) values ('apple')
insert into fruit(name) values ('strawberry')

select name from fruit

результат:

orange
apple
strawberry
...