TSQL - czy można zdefiniować kolejność sortowania?

Czy jest możliwe zdefiniowanie kolejności sortowania dla zwracanych wyników?

Chciałbym, aby kolejność sortowania była 'pomarańczowa ''jabłkowa ''truskawkowa', a nie rosnąca ani malejąca.

Wiem, że ORDER BY może zrobić ASC lub DESC, ale czy istnieje zdefiniowany ('pomarańczowy',' jabłkowy',' truskawkowy') Typ rzeczy?

To będzie działać na SQL Server 2000.

Author: Luke Girvin, 2011-01-25

7 answers

Jest niesamowicie niezgrabny, ale możesz użyć instrukcji CASE do zamawiania:

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

Alternatywnie można utworzyć tabelę pomocniczą, która zawiera pole sortowania i kolejność sortowania.

TargetValue  SortOrder
orange       1
apple        2
strawberry   3

I dołączyć swój stół do tego nowego stołu.

 49
Author: LittleBobbyTables,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-25 01:55:23

Use a CASE statement :

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

Składnia Alternatywna, z 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 
 10
Author: OMG Ponies,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-25 01:55:04

Jeśli ma to być krótkotrwałe Wymaganie, użyj case statement. Jeśli jednak wydaje ci się, że może istnieć przez jakiś czas i zawsze będzie to orange/apple/strawberry porządek (a nawet jeśli nie - patrz poniżej), możesz pomyśleć o poświęceniu trochę miejsca na dysku, aby zyskać trochę prędkości.

Utwórz nową kolumnę w tabeli o nazwie or_ap_st i użyj wyzwalacza insert/update, aby wypełnić ją liczbą 1, 2 lub 3, w zależności od wartości kolumny fruit. Następnie indeks na nim.

Ponieważ tylko wtedy, gdy dane w tej kolumnie ulegną zmianie, Jest to najlepszy czas, aby to zrobić. Koszt zostanie następnie poniesiony przy małej liczbie zapisów, a nie dużej liczbie odczytów, a zatem zamortyzowany na deklaracjach select.

Twoje zapytanie będzie wtedy ślepo szybkie:

select field1, field2 from table1
order by or_ap_st;

Bez funkcji per-row zabijających wydajność.

I, jeśli chcesz również inne rozkazy sortowania, cóż, dlatego zadzwoniłem do kolumny or_ap_st. Możesz dodać tyle innych sortowań kolumny według potrzeb.

 6
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-25 02:00:33

To co robię w tym przypadku to

ORDER BY
  CASE WHEN FRUIT = 'Orange' THEN 'A' 
       WHEN FRUIT = 'Apple' THEN 'B'
       WHEN FRUIT = 'Strawberry' THEN 'C'
       ELSE FRUIT
END
 2
Author: turtlepick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-25 01:56:27

Idąc dalej od odpowiedź turtlepicka :

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

Jeśli masz więcej elementów w FRUIT i zaczynają się od liter zdefiniowanych po słowach kluczowych THEN, elementy te pojawią się w zakodowanej kolejności. Na przykład banan pojawia się przed truskawką. Można go obejść za pomocą

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

Tutaj użyłem znaków z niższymi wartościami ASCII w nadziei, że nie pojawią się na początku wartości w FRUIT.

 1
Author: Kuitsi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:16

Dodaj klucz do tabeli (np. fruit_id int identity (1,1) primary key), aby zachować kolejność wstawiania

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

Wynik:

orange
apple
strawberry
 0
Author: The Danish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-06 19:38:59

Nie tak powszechne, ale dla operacji z pojedynczą wartością lub specyficznych wzorców, zastąp działa również

Np.

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
Author: Vland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-19 13:39:44