2011-01-25 21 views
19

È possibile definire un ordinamento per i risultati restituiti?TSQL - È possibile definire l'ordinamento?

Mi piacerebbe che l'ordinamento fosse 'arancia' 'mela' 'fragola' non ascendente o discendente.

So che ORDER BY può fare ASC o DESC ma c'è un DEFINED (tipo 'orange', 'apple', 'strawberry') tipo cosa?

Questo sarà in esecuzione su SQL Server 2000.

risposta

44

E 'incredibilmente goffo, ma è possibile utilizzare una dichiarazione CASE per l'ordine:

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

In alternativa, è possibile creare una tabella secondaria che contiene il campo di ordinamento e un ordinamento.

TargetValue SortOrder 
orange  1 
apple  2 
strawberry 3 

E unisciti al tuo tavolo su questo nuovo tavolo.

+14

Hah! Come ho intenzione di fidarsi di qualsiasi SQL provenienti da qualcuno chiamato LittleBobbyTables :-) – paxdiablo

+2

@pax - :-) – LittleBobbyTables

+0

1 per l'opzione tavolo, sempre più flessibile – RichardTheKiwi

9

Utilizzare un CASE statement:

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

sintassi alternativa, con una 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 
+0

Cosa devo fare se alcuni elementi vengono visualizzati alla fine dei risultati SELECT? – user1451111

2

Quello che faccio in questo caso è

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

Cosa devo fare se alcuni elementi compaiono alla fine dei risultati SELECT? – user1451111

5

Se questo sta per essere un requisito di breve durata, utilizzare un'istruzione caso. Tuttavia, se pensi che potrebbe essere in giro per un po ', e sarà sempre dell'ordine orange/apple/strawberry (o anche se non lo fosse - vedi sotto), potresti pensare di sacrificare lo spazio su disco per guadagnare un po' di velocità.

Creare una nuova colonna nella tabella denominata or_ap_st e utilizzare un trigger di inserimento/aggiornamento per popolare con il numero 1, 2 o 3, a seconda del valore della colonna di frutta. Quindi indicizzalo.

Poiché l'unica volta che i dati in quella colonna cambieranno è quando la riga cambia, quello è il momento migliore per farlo. Il costo verrà quindi sostenuto su un numero ridotto di scritture anziché su un numero elevato di letture, quindi ammortizzato sulle dichiarazioni select.

Vostri criteri sarà quindi un veloce come il fulmine:

select field1, field2 from table1 
order by or_ap_st; 

senza funzioni per-riga uccidendo le prestazioni.

E, se si desidera anche altri ordinamenti, beh, è ​​per questo che ho chiamato la colonna or_ap_st. Puoi aggiungere tutte le altre colonne di ordinamento di cui hai bisogno.

1

Andando più lontano dalla turtlepick's answer:

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

Nel caso in cui si dispone di alcuni altri elementi di frutta e capita di iniziare con le lettere definite Dopo di allora le parole chiave, quelle voci apparirebbero all'interno dell'ordine hardcoded. Per esempio Banana si presenta prima di Strawberry.Si può aggirare con

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

personaggi Qui ho usato con i valori più bassi ASCII in speranza che non avrebbero apparire all'inizio di valori nella frutta.

0

Aggiungere una chiave per la tavola (ad esempio int fruit_id identità (1,1) chiave primaria) per preservare l'ordine di inserimento

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 

risultato:

orange 
apple 
strawberry 
0

non così comune, ma per operazioni a valore singolo o modelli specifici, REPLACE funziona anche

es.

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 
Problemi correlati