2009-08-07 21 views

Respuesta

15
ORDER BY 
    CASE WHEN @switch = 0 THEN Field1 END, 
    CASE WHEN @Switch = 1 THEN Field2 END 
+1

Esto solo funciona cuando el Campo1 y el Campo2 son del mismo tipo. – edosoft

+1

Puede escribir esto como una expresión de caso ... CASO CUANDO @ switch = 0 THEN Campo1 WHEN @ switch = 1 THEN Field2 END – pjp

+2

Si cada CASE tiene una sola cláusula THEN, no necesita preocuparse de qué tipo los campos son. –

3

Una forma cruda:

IF @switch = 1 
    BEGIN 
    SELECT 
      acct_nbr, 
      acct_name 
    FROM 
      acct 
    ORDER BY acct_nbr 
    END 
ELSE 
    BEGIN 
    SELECT 
      acct_nbr, 
      acct_name 
    FROM 
      acct 
    ORDER BY acct_name 
    END 

También debe ser capaz de utilizar CASE..WHEN pienso:

SELECT 
    acct_nbr, 
    acct_name 
FROM 
    acct 
ORDER BY 
    CASE @switch 
    WHEN 1 THEN acct_nbr 
    WHEN 0 THEN acct_name 
    END 
2

Realmente no estoy seguro de que puedas? Que iba a terminar haciendo esto:

CREATE PROCEDURE [dbo].[CLICK10_GetCP] 
    @switch AS BIT 
AS 
    BEGIN 
     if @switch 
     begin 
      SELECT 
        acct_nbr, 
        acct_name 
      FROM 
        acct 
      ORDER BY 
        acct_nbr 
     end 
     else 
     begin 
      SELECT 
        acct_nbr, 
        acct_name 
      FROM 
        acct 
      ORDER BY 
        acct_name 
     end 
    END 
GO 
+1

usted puede hacerlo mediante el uso de una instrucción CASE en el ORDER BY, pero si la consulta es sufficently compleja, el método será más rápido. –

0
SELECT 
      acct_nbr, 
      acct_name 
    FROM 
      acct 
    ORDER BY case @switch when 1 then acct_name else acct_nbr end 
+0

Esto solo funciona cuando acct_nbr y acct_name tienen el mismo tipo de datos, o son convertibles entre sí. – edosoft

+0

Cierto, pero es una técnica útil. –

1

pensé que podría cambiar el parámetro a un int, y ordenar por la columna con el ordinal:

CREATE PROCEDURE [dbo].[CLICK10_GetCP] 
    @ordinal AS INT 
AS 
    BEGIN 
     SELECT 
       acct_nbr, 
       acct_name 
     FROM 
       acct 
     ORDER BY @Ordinal 

    END 
GO 

Esto arroja un error agradable (SQL2005):

Msg 1008, nivel 16, estado 1, línea 4 el elemento Seleccione identificado por el ORDER BY número 1 contiene una variable como parte de la expresión que identifica una posición de columna. Las variables son solo permitidas al ordenar por una expresión que hace referencia al nombre de una columna.

alrededor de google encontró this solution here (SQL 2005 en adelante):

CREATE PROCEDURE [dbo].[CLICK10_GetCP] 
    @switch AS BIT 
AS 
    BEGIN 
     SELECT 
       acct_nbr, 
       acct_name 
     FROM 
       acct 
     ORDER BY CASE 
      WHEN @switch = 0 THEN (RANK() OVER (ORDER BY acct_nbr, acct_name)) 
      WHEN @switch = 1 THEN (RANK() OVER (ORDER BY acct_name, acct_nbr)) 
     END 
GO 
0

El enfoque más sucinta es:

CREATE PROCEDURE [dbo].[CLICK10_GetCP] 
    @switch AS BIT 
AS 
    BEGIN 
     SELECT 
       acct_nbr, 
       acct_name 
     FROM 
       acct 
     ORDER BY 
       case @switch 
        when 1 then acct_nbr 
        when 0 then acct_name 
       end 

    END 
GO 

Esto puede resultar en un plan de ejecución pobre por mayor tablas, o puede no funcionar en absoluto si acc-nbr es un int y acct-name es varchar.

Envolver dos consultas separadas en declaraciones IF/ELSE puede funcionar notablemente mejor para conjuntos de datos más grandes o ser el único enfoque factible si los tipos de datos de las dos columnas son diferentes.

3

Una forma es construir el algo consulta como esta:

CREATE PROCEDURE [dbo].[CLICK10_GetCP] 
    @switch AS BIT 
AS 
DECLARE 
@SQL nvarchar(max) 


    SET @SQL N'SELECT 
      acct_nbr, 
      acct_name 
    FROM 
      acct 
    ORDER BY ' 

if(@switch) 
BEGIN 
    @SQL = @SQL + ' acct_nbr ' 
END 
ELSE 
BEGIN 
    @SQL = @SQL + ' acct_Name ' 
END 

Exec SP_ExecuteSQL @SQL 
Cuestiones relacionadas