Jak dokonać warunkowego zamawiania dla dwóch lub więcej kolumn

10

W MS SQL Server 2005 piszę jedno zapytanie z sortowaniem warunkowym, a moim problemem jest to, że nie wiem, jak mogę sortować warunkowo za pomocą dwóch kolumn?

Jeśli napisałem taki kod, działa normalnie

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

Nie wiem, jak zrobić warunkowe porządkowanie dla dwóch lub więcej kolumn

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

Jest pomysł, aby zrobić dynamiczny TSQL i używać go, sp_executesqlale wciąż szukam lepszego pomysłu?

adopilot
źródło
Możesz także sprawdzić Czy ma sens SPRAWA .. KONIEC w ZAMÓWIENIU PRZEZ? . Chociaż pytanie to zostało postawione w kontekście PostgreSQL, większość komentarzy i rozważań dynamicznych zapytań WRT vs CASEmoże mieć zastosowanie w tym przypadku.
joanolo,

Odpowiedzi:

12

Przyznaję, że nigdy wcześniej nie musiałem tego robić, więc było trochę drapania w głowie. Prosta przykładowa tabela do zademonstrowania:

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')

Używając parametru @SortStyle do rozróżnienia między sortowaniem, @SortStyle = 1 będzie sortować według, col1 ASC, col2 DESCa @ SortStyle = 2 sortuje według 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

W jaki sposób ZAMÓWIĆ WEDŁUG parametru obejmuje prostszy przypadek sortowania według tylko 1 kolumny.

Mark Storey-Smith
źródło
5

Zakładając, że masz więcej przypadków (dodałem jeden) i wszystkie typy są kompatybilne,

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

Nie jest to sortowanie wielokolumnowe: masz sortowanie podstawowe, a następnie sortowanie wtórne. Wystarczy spojrzeć na okno dialogowe sortowania w programie Excel, aby zobaczyć, co mam na myśli.

gbn
źródło
1

Podany przykład jest prosty:

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

Istnieje pomysł, aby zrobić dynamiczny TSQL i używać go, sp_executesqlale wciąż szukam lepszego pomysłu.

Zawsze dobrze jest unikać dynamicznego SQL, jeśli to możliwe

Jack mówi, że spróbuj topanswers.xyz
źródło