2011-02-14 15 views
5

Deseo solicitar una consulta de selección SQL donde hay 2 campos que están en el orden por. Entonces necesito decidir si uno es Descendente y el otro Ascendente. Cómo se hace estocómo ordenar 2 campos de SQL en asc y desc dinámicamente

Quiero algo como:

Select * from Customer 
Order By Date @asc_or_Desc_date, Name @asc_or_Desc_name 

Alguien tiene alguna idea?

He intentado esto pero parece fallar

SELECT 

    Customer_ID,       
    Name,        
    Age           

FROM #Customer 
ORDER BY 

    CASE WHEN @fieldSort ='Name' 
     THEN ROW_NUMBER() over (order by Name) * 
      case when @directionOfSort = 'A' 
       THEN 1 ELSE -1 END, 
      ROW_NUMBER() over (order by Age) * 
      case when @directionOfSort = 'A' 
       THEN 1 ELSE -1 END, 
     END 

Alguien sabe cómo ordenar esto?

+0

Si va a agregar más detalles a su pregunta, intente hacerlo de tal forma que nuestras respuestas no sean irrelevantes por eso. Si ve eso probable, mejor publique una nueva pregunta, posiblemente con referencia a esta, si es necesario. –

Respuesta

3

Usted tendrá que crear la instrucción SQL de forma dinámica con el fin de utilizar una variable:

DECLARE @asc_desc VARCHAR(4); 

SET @asc_desc = 'DESC'; 

DECLARE @sql NVARCHAR(1000); 

SET @sql = 'Select * from Customer Order By Date ' + @asc_desc + ', Name'; 

EXEC sp_executesql @sql 

Esto orden de fecha y DESCENDING Nombre ASCENDING.

Solo necesita agregar DESC si desea usar DESCENDING como ASCENDING es el valor predeterminado.

+0

'sp_execute' necesita' EXEC' antes en este caso. –

+0

@Andriy M: Sí, estaba intentando ejecutar el código en SSMS, así como corregir la pregunta. –

+1

NOTA: tenga muy en cuenta la inyección SQL al hacer esto. Los parámetros deben ser suministrados por su propio código y/o los valores deben validarse. Si hace esto dentro de un procedimiento almacenado, revíselos dentro del procedimiento almacenado, solo para estar seguro. – MatBailie

2

En SQL Server 2005 + se podría emplear el siguiente dispositivo:

WITH CustomerCTE AS (
    SELECT 
    *, 
    DateSort = ROW_NUMBER() OVER (ORDER BY Date), 
    NameSort = ROW_NUMBER() OVER (ORDER BY Name) 
    FROM Customer 
) 
SELECT * 
FROM CustomerCTE 
ORDER BY DateSort * @DateSortDir, NameSort * @NameSortDir 

Los VARs en este caso debería ser 1 o -1.


EDITAR

El ejemplo adicionalmente publicado parece dar a entender que el orden de las columnas a utilizar en ORDER BY debe ser dinámica también. Y ahora también parece que la dirección del pedido se especifica uniformemente para ambas columnas.

Si es así o no (la pregunta se ha vuelto un poco más ambigua), ambos se asumen en mi segunda solución.

DECLARE @IntSortDir int; 
SET @IntSortDir = CASE @directionOfSort WHEN 'A' THEN 1 ELSE -1 END; 

WITH CustomerCTE AS (
    SELECT 
    Customer_ID, 
    Name, 
    Age, 
    NameSort = ROW_NUMBER() OVER (ORDER BY Name), 
    AgeSort = ROW_NUMBER() OVER (ORDER BY Date) 
    FROM Customer 
) 
SELECT 
    Customer_ID, 
    Name, 
    Age 
FROM CustomerCTE 
ORDER BY 
    CASE @fieldSort WHEN 'Age' THEN AgeSort END * @IntSortDir, 
    NameSort * @directionOfSort, 
    CASE @fieldSort WHEN 'Name' THEN AgeSort END * @IntSortDir 

@fieldSort especifica la columna de orden primario. El otro se convierte automáticamente en el secundario.

+0

SELECT \t EXT_Design_Standard_ID \t \t \t \t \t \t \t Standards_Name \t \t \t \t \t \t \t \t \t Ref \t \t \t \t \t \t \t \t \t \t \t DE #LastUpdateTemp --ORDER POR Date_Changed DESC ORDER BY \t \t CASO CUANDO @fieldSort = 'Nombre Normas' \t \t ENTONCES ROW_NUMBER() sobre (orden por Standards_Name) * caso \t \t \t cuando @directionOfSort = 'A' \t \t \t \t ENTONCES 1 ELSE -1 END, \t \t \t \t ROW_NUMBER() sobre (orden por Ref) * \t \t \t caso cuando @directionOfSort = 'A' \t \t \t \t then 1 else -1 FIN, \t \t FIN, – user532104

+0

problema minas falla, alguna idea de cómo solucionarlo? – user532104

+0

¿Quiere decir que no solo quiere que la dirección de ordenamiento sea dinámica, sino también el orden de las columnas 'ORDER BY'? –

5
SELECT 
    Customer_ID,       
    Name,        
    Age           
FROM 
    #Customer 
ORDER BY 
    CASE WHEN @field = 'Name' AND @direction = 'A' THEN Name ELSE NULL END ASC, 
    CASE WHEN @field = 'Name' AND @direction = 'D' THEN Name ELSE NULL END DESC, 
    CASE WHEN @field = 'Age' AND @direction = 'A' THEN Age ELSE NULL END ASC, 
    CASE WHEN @field = 'Age' AND @direction = 'D' THEN Age ELSE NULL END DESC 


no me gustaría hacer que más de muchas combinaciones diferentes sin embargo. Si usted tiene una gran cantidad de combinaciones que haría somethign basado en la siguiente ...

SELECT 
    Customer_ID,       
    Name,        
    Age           
FROM 
(
    SELECT 
    Customer_ID, 
    Name, 
    ROW_NUMBER() OVER (ORDER BY Name) AS "name_order", 
    Age, 
    ROW_NUMBER() OVER (ORDER BY Age) AS "age_order" 
    FROM 
    #Customer 
) 
    AS [data] 
ORDER BY 
    CASE @field1 
    WHEN 'Name' THEN CASE @direction1 WHEN 'A' THEN name_order ELSE -name_order END 
    WHEN 'Age' THEN CASE @direction1 WHEN 'A' THEN age_order ELSE -age_order END 
    ELSE NULL 
    END, 
    CASE @field2 
    WHEN 'Name' THEN CASE @direction2 WHEN 'A' THEN name_order ELSE -name_order END 
    WHEN 'Age' THEN CASE @direction2 WHEN 'A' THEN age_order ELSE -age_order END 
    ELSE NULL 
    END 

repetir tantas veces como sea necesario ...


Nota: Justo porque se puede hacer de esta manera, no significa que deba hacerse de esta manera.

+0

+1 para el primero, incluso si es más engorroso, porque el segundo solo ordena por una columna, mientras que parece que el OP lo quiere ser por dos. –

+0

La pregunta es Nombre Edad, y Asc ¿Desc? Aunque pueda estar siendo ciego, no es raro ... – MatBailie

+0

La misma lógica, pero ligeramente refactorizada, para que sea obvio cómo extender a varias órdenes. – MatBailie

1
Here is the solution 

Explanation: 
1. Ordering the row number on the basis of SQL input param order by (DESC, ASC) 
2. Againt ordering the row number in outer query 

Try this code (working) 

DECLARE @PageNum int 
DECLARE @PageSize int 
DECLARE @TotalRowsNum int 
DECLARE @SortColumn varchar(200) 
DECLARE @SortOrder varchar(5) 

SET @PageNum = 4; 
SET @PageSize = 10; 
SET @SortColumn = 'CODE_ID'; 
SET @SortOrder = 'DESC'; 

WITH QueryResult AS 
(

SELECT *, 
CASE @SortOrder WHEN 'ASC' THEN 
ROW_NUMBER() OVER(ORDER BY @SortColumn ASC) 
ELSE 
ROW_NUMBER() OVER(ORDER BY @SortColumn DESC) 
END AS 'RowNumber' 

FROM TABLE_NAME 
) 
SELECT * FROM QueryResult 
WHERE RowNumber BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize 
ORDER BY RowNumber ASC 
Cuestiones relacionadas