2010-10-08 7 views
13

MySQL proporciona una función de cadena llamada FIELD() que acepta una cantidad variable de argumentos. El valor de retorno es la ubicación del primer argumento en la lista de los restantes. En otras palabras:¿Cuál es la capacidad del servidor MS SQL similar a la función FIELD() de MySQL?

FIELD('d', 'a', 'b', 'c', 'd', 'e', 'f') 

devolvería 4 dado que 'd' es el cuarto argumento después del primero.

Esta función proporciona la capacidad de ordenar los resultados de una consulta en base a un orden muy específico. Para mi aplicación actual, hay cuatro estados que necesito para administrar: activo, aprobado, rechazado y enviado. Sin embargo, si simplemente ordeno por la columna de estado, siento que la usabilidad de la lista resultante se ve disminuida ya que los artículos rechazados y activos son más importantes que los enviados y aprobados.

En MySQL que podría hacer esto:

SELECT <stuff> FROM <table> WHERE <conditions> ORDER BY FIELD(status, 'rejected', 'active','submitted', 'approved') 

y los resultados serían ordenados de tal manera que los elementos fueron en primer lugar, seguido de los activos, y así sucesivamente rechazado. Por lo tanto, los resultados se ordenaron en niveles decrecientes de importancia para el visitante.

Podría crear una tabla separada que enumere este nivel de importancia para los estados y luego ordenar la consulta por orden descendente, pero esto me ha surgido algunas veces desde que cambié a MS SQL Server, así que pensé que ' d pregunto si puedo o no evitar la tabla adicional y las consultas algo más complejas usando una función incorporada similar a FIELD() de MySQL.

Gracias,
David Kees

Respuesta

19

Utilice un CASE expression (SQL Server 2005 +):

ORDER BY CASE status 
      WHEN 'active' THEN 1 
      WHEN 'approved' THEN 2 
      WHEN 'rejected' THEN 3 
      WHEN 'submitted' THEN 4 
      ELSE 5 
     END 

Se puede utilizar esta sintaxis para una evaluación más compleja (incluyendo combinaciones, o si es necesario use LIKE)

ORDER BY CASE 
      WHEN status LIKE 'active' THEN 1 
      WHEN status LIKE 'approved' THEN 2 
      WHEN status LIKE 'rejected' THEN 3 
      WHEN status LIKE 'submitted' THEN 4 
      ELSE 5 
     END 
+0

cosas impresionante! Gracias. –

0

Recomiendo un CTE (SQL server 2005+). No es necesario repetir los códigos de estado o crear la tabla por separado.

WITH cte(status, RN) AS ( -- CTE to create ordered list and define where clause 
     SELECT 'active', 1 
UNION SELECT 'approved', 2 
UNION SELECT 'rejected', 3 
UNION SELECT 'submitted', 4 
) 
SELECT <field1>, <field2> 
FROM <table> tbl 
INNER JOIN cte ON cte.status = tbl.status -- do the join 
ORDER BY cte.RN -- use the ordering defined in the cte 

Buena suerte,

Jason

Cuestiones relacionadas