2011-01-25 9 views
19

¿Es posible definir un orden de clasificación para los resultados devueltos?TSQL - ¿Es posible definir el orden de clasificación?

Me gustaría que el orden de clasificación sea 'naranja' 'manzana' 'fresa' no ascendente o descendente.

Sé que ORDER BY puede hacer ASC o DESC, pero ¿hay algún tipo de cosa DEFINIDA ('naranja', 'manzana', 'fresa')?

Esto va a correr en SQL Server 2000.

Respuesta

44

Es increíblemente torpe, pero se puede utilizar una declaración CASE para ordenar:

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

Alternativamente, puede crear una tabla secundaria que contenga el campo de clasificación y un orden de clasificación.

TargetValue SortOrder 
orange  1 
apple  2 
strawberry 3 

Y une tu mesa a esta nueva mesa.

+14

¡Hah! Como si fuera a confiar en cualquier SQL proveniente de alguien llamado LittleBobbyTables :-) – paxdiablo

+2

@pax - :-) – LittleBobbyTables

+0

+1 para la opción de mesa, siempre más flexible – RichardTheKiwi

9

Utilice un CASE statement:

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

sintaxis alternativa, con una cosa:

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

¿Qué sucede si quiero que aparezcan ciertos elementos al final de los resultados de SELECCIONAR? – user1451111

2

Lo que hago en ese caso es

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

¿Qué ocurre si quiero que aparezcan ciertos elementos al final de los resultados SELECCIONAR? – user1451111

5

Si esto va a ser un requisito de corta duración, usar una declaración de caso. Sin embargo, si cree que puede estar por un tiempo, y siempre va a ser el orden orange/apple/strawberry (o incluso si no, consulte a continuación), es posible que desee pensar en sacrificar algo de espacio en disco para ganar algo de velocidad.

Cree una nueva columna en su tabla llamada or_ap_st y use un disparador de inserción/actualización para completarla con el número 1, 2 o 3, dependiendo del valor de la columna de su fruta. Luego indexe en él.

Como la única vez que cambian los datos en esa columna es cuando cambia la fila, ese es el mejor momento para hacerlo. El costo se incurrirá en un pequeño número de escrituras en lugar de en un gran número de lecturas, por lo tanto, se amortiza en las declaraciones select.

Su consulta será entonces un tan rápidos:

select field1, field2 from table1 
order by or_ap_st; 

sin funciones por fila matando el rendimiento.

Y, si quiere otros tipos de órdenes también, bien, es por eso que llamé a la columna or_ap_st. Puede agregar tantas otras columnas de clasificación como necesite.

1

Yendo más lejos de turtlepick's answer:

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

En caso de que ya tenga algunos componentes en más frutas y pasan a comenzar con las letras definidas después de entonces palabras clave, los elementos aparecerían dentro del orden codificado. Por ejemplo, Banana aparece antes de Strawberry.Puede eludir con

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

caracteres Aquí he utilizado con valores ASCII inferiores en la esperanza de que no aparecerían en el comienzo de los valores en la fruta.

0

Añadir una clave para la tabla (por ejemplo, identidad int fruit_id (1,1) clave primaria) para preservar el orden de inserción

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 

resultado:

orange 
apple 
strawberry 
0

No es tan común, pero para operaciones de valor único o patrones específicos, REEMPLAZAR también funciona

por ejemplo.

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 
Cuestiones relacionadas