Как сделать условный порядок для двух или более столбцов


10

В MS SQL Server 2005 я пишу один запрос с условной сортировкой, и моя проблема в том, что я не знаю, как я могу сортировать условно, используя два столбца?

Если я написал такой код, он работает нормально

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

Я не знаю, как сделать условный порядок для двух или более столбцов

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

Есть идея сделать динамический TSQL и использовать, sp_executesqlно я все еще ищу лучшую идею?



Вы также можете проверить, имеет ли смысл иметь CASE .. END в ORDER BY? , Несмотря на то, что вопрос был поставлен в контексте PostgreSQL, большинство замечаний и соображений WRT динамического запроса против CASEможет быть применимо к данному случаю.
Жоаноло

Ответы:


12

Я признаю, что мне никогда не приходилось делать это раньше, поэтому было немного царапин на голове. Простой пример таблицы для демонстрации:

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

Используя параметр @SortStyle для различения порядков сортировки, @SortStyle = 1 будет сортировать по, col1 ASC, col2 DESCа @ SortStyle = 2 - по 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

Как вы ORDER BY параметр охватывает более простой случай сортировки всего 1 столбец.


5

Предполагая, что у вас есть больше случаев (я добавил один), и все типы совместимы,

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

Это не сортировка по нескольким столбцам: у вас есть первичная сортировка, за которой следует вторичная сортировка. Просто посмотрите на диалоговое окно сортировки в Excel, чтобы понять, что я имею в виду.


1

С приведенным вами примером это просто:

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

Есть идея сделать динамический TSQL и использовать, sp_executesqlно я все еще ищу лучшую идею.

Всегда приятно избегать динамического SQL, где это возможно

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.