2010-10-07 14 views
12

Escribir un procedimiento almacenado en MS SQL Server 2008 R2, quiero evitar el uso de DSQL ...condicional SQL ORDER POR ASC/DESC para columnas alfa

Me gustaría que el método sort (ASC o DESC) para ser condicional.

Ahora, con una columna numérica Me basta con utilizar una declaración de caso y negar el valor de emular ASC o DESC ... Es decir:

... ORDER BY CASE @OrderAscOrDesc WHEN 0 THEN [NumericColumn] ELSE -[NumericColumn] END ASC 

Qué es un método apropiado para hacer esto con una Columna alfa?

EDIT: Pensé en una manera inteligente, pero parece terriblemente ineficiente ... Podría insertar mi columna alfa ordenada en una tabla temporal con un autonumber y luego ordenar por el autonumber utilizando el método descrito anteriormente.

Edit2:

¿Qué piensan ustedes de este enfoque?

ORDER BY CASE @OrderAscOrDesc WHEN 0 THEN [AlphaColumn] ELSE '' END ASC, 
CASE @OrderAscOrDesc WHEN 0 THEN '' ELSE [AlphaColumn] END DESC 

No sé si forzando una especie en una columna uniforme es más eficiente que derivar los números de cadenas ordenadas aunque

Respuesta

27

Una opción

;WITH cQuery AS 
(
    SELECT 
     *, 
     ROW_NUMBER() OVER (ORDER BY SortColumn) AS RowNum 
    FROM 
     MyTable 
) 
SELECT 
    * 
FROM 
    cQuery 
ORDER BY 
    RowNum * @Direction --1 = ASC or -1 = DESC 

o caja, que en mi humilde opinión es un poco más feo

ORDER BY 
    CASE WHEN 'ASC' THEN SortColumn ELSE '' END ASC, 
    CASE WHEN 'DESC' THEN SortColumn ELSE '' END DESC 
+0

inteligente, bastante similar a mi solución que he publicado en la edición. Espero algo más eficiente que derivar otra copia ordenada de los datos solo para generar un orden de clasificación numérico ... – Matthew

+0

@Matthew PK: debe sustituir la cadena por un número coincidente o agregar ordenaciones ficticias para no casos relevantes. Nada * realmente * inteligente Tengo miedo – gbn

+0

¿Qué opinas sobre el enfoque de "dos cláusulas ORDER BY" en mi segunda edición? – Matthew

1

Este es uno de esos casos en que las soluciones específicas pueden ser preferibles rable a los genéricos, especialmente cuando manejamos grandes cantidades de datos. Yo:

IF @OrderAscOrDesc = 0 THEN BEGIN 
    SELECT ... 
    FROM ... 
    ORDER BY [AlphaColumn] ASC 
END ELSE BEGIN 
    SELECT ... 
    FROM ... 
    ORDER BY [AlphaColumn] DESC 
END 

Si usted tiene un índice en [AlphaColumn], es posible que a veces conseguir un mejor plan con una consulta más específica, que con un genérico de una sola talla para todos uno.

Editar: para facilitar la reutilización de código, se puede envolver su selecto en un UDF en línea - se llevará a cabo del mismo modo que:

IF @OrderAscOrDesc = 0 THEN BEGIN 
    SELECT ... 
    FROM YourInlineUdf(...) 
    ORDER BY [AlphaColumn] ASC 
END ELSE BEGIN 
    SELECT ... 
    FROM YourInlineUdf(...) 
    ORDER BY [AlphaColumn] DESC 
END 
+0

Estoy de acuerdo con el principio de que ' ve establecido. En mi aplicación particular, preferiría no hacer esto porque la consulta es relativamente larga y utiliza varias combinaciones. Mi preocupación sería duplicar el código 6 veces más o menos, dificultando el mantenimiento y las futuras actualizaciones. – Matthew

+0

@Matthew PK: para facilitar la reutilización del código, puede ajustar su selección en una UDF en línea; funcionará igual de bien –