Упорядочить по нескольким столбцам в SQL Server

У меня есть таблица в SQL Server, в которой мне нужно выбрать данные, отсортированные по значению. Например,

  • Если значение сортировки равно 1, то мне нужно отсортировать по column1, column2, а затем column3.

  • Если значение сортировки равно 2, то мне нужно отсортировать по column2, column1, а затем column3.

  • Если значение сортировки равно 3, то мне нужно отсортировать по column3, column1, а затем column2.

Может кто-нибудь сказать мне, как я могу добиться этого в SQL без использования, если еще, как показано ниже:

IF @SortOrder = 1
THEN
    SELECT * 
    FROM table 
    ORDER BY c1, c2, c3
END

IF @SortOrder = 2
THEN
    SELECT * 
    FROM table 
    ORDER BY c2, c1, c3
END

IF @SortOrder = 3
THEN
    SELECT * 
    FROM table 
    ORDER BY c3, c1, c2
END

5 ответов

Решение

Ты можешь использовать CASE EXPRESSION для условного заказа:

SELECT * FROM Table
ORDER BY CASE WHEN @SortOrder = 1 then c1
              WHEN @SortOrder = 2 then c2
              ELSE c3
         END,
         CASE WHEN @SortOrder = 1 then c2
              ELSE  c1
         END,
         CASE WHEN @SortOrder in(1,2) then c3
              ELSE c2
         END

Использование CASE является правильным. Вам нужен этот синтаксис, если тип данных конфликтует в столбцах (c1,c2,c3).

ORDER BY
  CASE WHEN @SortOrder = 1 THEN c1 END,
  CASE WHEN @SortOrder = 1 THEN c2 END,
  CASE WHEN @SortOrder = 1 THEN c3 END,
  CASE WHEN @SortOrder = 2 THEN c2 END,
  CASE WHEN @SortOrder = 2 THEN c1 END,
  CASE WHEN @SortOrder = 2 THEN c3 END,
  CASE WHEN @SortOrder = 3 THEN c3 END,
  CASE WHEN @SortOrder = 3 THEN c1 END,
  CASE WHEN @SortOrder = 3 THEN c2 END

Я думаю dynamic query лучший подход здесь для условного заказа

DECLARE @sql       VARCHAR(max),
        @SortOrder INT = 2

SET @sql = 'select * from table order by ' 
            + CASE @SortOrder WHEN 1 THEN 'c1,c2,c3' WHEN 2 THEN 'c2,c1,c3' WHEN 3 THEN 'c3,c1,c2' END 

--print @sql
exec (@sql)

Вы можете использовать CASE утверждение в вашем ORDER BY пункт и COALESCE ценности. (Обратите внимание, что вам, возможно, потребуется проверить производительность при использовании этой настройки. У меня обычно нет проблем, но я решил, что это замечу.)

SELECT *
FROM [TABLE]
ORDER BY
    CASE @SortOrder
    WHEN 1 THEN COALESCE(c1, N'') + N'-' + COALESCE(c2, N'') + N'-' + COALESCE(c3, N'')
    WHEN 2 THEN COALESCE(c2, N'') + N'-' + COALESCE(c1, N'') + N'-' + COALESCE(c3, N'')
    WHEN 3 THEN COALESCE(c3, N'') + N'-' + COALESCE(c1, N'') + N'-' + COALESCE(c2, N'')
        END

Или, если вы хотите, чтобы значение, по которому вы сортировали, возвращалось в ваших результатах (но столбец Порядок сортировки должен быть первым столбцом)

SELECT
    CASE @SortOrder
    WHEN 1 THEN COALESCE(c1, N'') + N'-' + COALESCE(c2, N'') + N'-' + COALESCE(c3, N'')
    WHEN 2 THEN COALESCE(c2, N'') + N'-' + COALESCE(c1, N'') + N'-' + COALESCE(c3, N'')
    WHEN 3 THEN COALESCE(c3, N'') + N'-' + COALESCE(c1, N'') + N'-' + COALESCE(c2, N'')
        END AS SortOrder
    *
FROM [TABLE]
ORDER BY 1

Может быть, попробовать что-то вроде этого: select * from table order by @SortOrder,c1,c2,c3если значение представляет порядок столбцов, иначе вы можете попытаться добавить смещение (например, @SortOrder + 4)

Другие вопросы по тегам