Comment effectuer un classement conditionnel pour deux colonnes ou plus

10

Dans MS SQL Server 2005, j'écris une requête avec un tri conditionnel et mon problème est que je ne sais pas comment puis-je trier conditionnellement en utilisant deux colonnes?

Si j'ai écrit du code comme ça, ça fonctionne normalement

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

Je ne sais pas comment effectuer une commande conditionnelle pour deux colonnes ou plus

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

Il y a une idée pour faire du TSQL dynamique et l'utiliser sp_executesqlmais je cherche toujours une meilleure idée?

adopilot
la source
doublon possible de l'erreur "Échec
gbn
Vous pouvez également vérifier Est-il judicieux que CASE .. END se termine par ORDER BY? . Bien que cette question ait été posée dans le contexte de PostgreSQL, la plupart des commentaires et des considérations de la requête dynamique WRT vs CASEpeuvent s'appliquer à ce cas.
joanolo

Réponses:

12

J'admets que je n'ai jamais eu à le faire auparavant, donc il y a eu un peu de grattage de tête. Exemple de tableau simple pour démontrer:

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

En utilisant un paramètre @SortStyle pour différencier les ordres de tri, @SortStyle = 1 triera par col1 ASC, col2 DESCet @ SortStyle = 2 triera par 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

Comment ORDER BY un paramètre couvre le cas le plus simple du tri par une seule colonne.

Mark Storey-Smith
la source
5

En supposant que vous avez plus de cas (j'en ai ajouté un) et que tous les types sont 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

Ce n'est pas un tri multi-colonnes: vous avez un tri primaire, suivi d'un tri secondaire. Regardez simplement la boîte de dialogue de tri dans Excel pour voir ce que je veux dire.

gbn
la source
1

Avec l'exemple que vous donnez, c'est simple:

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

Il y a une idée pour faire du TSQL dynamique et l'utiliser sp_executesqlmais je cherche encore une meilleure idée.

Il est toujours agréable d'éviter autant que possible le SQL dynamique

Jack dit d'essayer topanswers.xyz
la source