Cómo hacer un pedido condicional para dos o más columnas

10

En MS SQL Server 2005, estoy escribiendo una consulta con clasificación condicional y mi problema es que no sé cómo puedo ordenar condicional usando dos columnas.

Si escribí un código como este, está funcionando normalmente

select
    *
from 
    table
order by 
    case @pkr 
           when 'kol' then kol
           when 'nci' then nci
    end

No sé cómo hacer un pedido condicional para dos o más columnas.

select
    *
from 
    table
order by 
    case @pkr
        when 'KOL-NCI' then kol,nci
        when 'kol-MPCI' then kol,mpci
    end

¿Existe una idea para hacer TSQL dinámico y usarlo sp_executesqlpero todavía estoy buscando una mejor idea?

adopilot
fuente
También puede marcar ¿Tiene sentido tener CASE .. END en un ORDER BY? . Aunque esa pregunta se planteó en el contexto de PostgreSQL, la mayoría de los comentarios y consideraciones de la consulta dinámica WRT vs CASEpueden ser aplicables a este caso.
joanolo

Respuestas:

12

Admito que nunca he tenido que hacer esto antes, así que hubo un poco de rascarse la cabeza. Tabla de ejemplo simple para demostrar:

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[MyTable]') AND type in (N'U'))
    DROP TABLE [dbo].[MyTable]
GO

CREATE TABLE dbo.MyTable
(
    col1 INT
    , col2 CHAR(1)
)
GO

INSERT dbo.MyTable (col1, col2) VALUES (1, 'A')
INSERT dbo.MyTable (col1, col2) VALUES (1, 'B')
INSERT dbo.MyTable (col1, col2) VALUES (1, 'C')
INSERT dbo.MyTable (col1, col2) VALUES (2, 'A')
INSERT dbo.MyTable (col1, col2) VALUES (2, 'B')
INSERT dbo.MyTable (col1, col2) VALUES (2, 'C')
INSERT dbo.MyTable (col1, col2) VALUES (3, 'A')
INSERT dbo.MyTable (col1, col2) VALUES (3, 'B')
INSERT dbo.MyTable (col1, col2) VALUES (3, 'C')

Usando un parámetro @SortStyle para diferenciar entre las órdenes de clasificación, @SortStyle = 1 ordenará por col1 ASC, col2 DESCy @ SortStyle = 2 ordenará por col2 DESC, col1 ASC.

DECLARE @SortStyle INT
SET @SortStyle = 1

SELECT
    col1
    , col2
FROM
    dbo.MyTable
ORDER BY
    CASE
        WHEN @SortStyle = 1 THEN col1
    END ASC,
    CASE
        WHEN @SortStyle = 1 THEN col2
    END DESC,
    CASE
        WHEN @SortStyle = 2 THEN col2
    END DESC,
    CASE
        WHEN @SortStyle = 2 THEN col1
    END ASC

SET @SortStyle = 2

SELECT
    col1
    , col2
FROM
    dbo.MyTable
ORDER BY
    CASE
        WHEN @SortStyle = 1 THEN col1
    END ASC,
    CASE
        WHEN @SortStyle = 1 THEN col2
    END DESC,
    CASE
        WHEN @SortStyle = 2 THEN col2
    END DESC,
    CASE
        WHEN @SortStyle = 2 THEN col1
    END ASC

¿Cómo ORDER BY un parámetro cubre el caso más simple de ordenar por solo 1 columna?

Mark Storey-Smith
fuente
5

Suponiendo que tiene más casos (agregué uno) y todos los tipos son compatibles,

order by 
    case @pkr
        when 'KOL-NCI' then kol
        when 'kol-MPCI' then kol
        when 'foo-bar' then foo
    end,
    case @pkr
        when 'KOL-NCI' then nci
        when 'kol-MPCI' then mpci
        when 'foo-bar' then bar 
    end

No es una clasificación de varias columnas: tiene una clasificación primaria, seguida de una clasificación secundaria. Solo mira el cuadro de diálogo de clasificación en Excel para ver a qué me refiero.

gbn
fuente
1

Con el ejemplo que das es simple:

select *
from table
order by kol, case @pkr
                when 'KOL-NCI' then nci
                when 'kol-MPCI' then mpci
              end

Hay una idea para hacer TSQL dinámico y usarlo, sp_executesqlpero todavía estoy buscando una mejor idea.

Siempre es bueno evitar el SQL dinámico siempre que sea posible

Jack dice que intente topanswers.xyz
fuente