Неверный синтаксис для предложения Order by с несколькими столбцами - PullRequest
0 голосов
/ 09 января 2019

Как записать порядок по предложению с несколькими столбцами в регистре?

 ORDER BY 
 CASE 
 WHEN @T='ABC' Then Val,Seq
 ELSE Seq END

Также пробовал

 ORDER BY 
 CASE 
 WHEN @T='ABC' Then Convert(int,Val) 
 WHEN @T='ABC' Then Convert(nvarchar,Seq)
 ELSE Seq END

 ORDER BY 
 CASE 
 WHEN @T='ABC' Then Val,Seq
 ELSE Seq END

Также приведенный ниже код выдает ошибку:

«Этот оператор выдает ошибку:« Преобразование не удалось при преобразовании значения nvarchar 'EX-02-60' в тип данных int "при выполнении хранимой процедуры."

Ответы [ 3 ]

0 голосов
/ 09 января 2019

Тип данных значения в ORDER BY всегда должен быть одинаковым. Здесь вы получите ошибку преобразования, потому что в первом случае тип данных - INT, а во втором - Varchar. SO Для более безопасного способа вы можете использовать следующий подход

;WITH CTE
AS
(
    SELECT
        RN_Val = ROW_NUMBER() OVER(ORDER BY Val),
        RN_Seq = ROW_NUMBER() OVER(ORDER BY Seq),
        *
        FROM YourTable
)
SELECT
    *
    FROM CTE
        ORDER BY 
        (
            CASE @T
                WHEN 'ABC' THEN RN_Val
                WHEN 'XYZ' THEN RN_Seq
            END
        )
0 голосов
/ 09 января 2019

Давайте создадим таблицу, в которой есть ваши столбцы

CREATE TABLE T(
  Val VARCHAR(45),
  Seq INT,
  Sequence INT
);

INSERT INTO T VALUES
('A', 1, 2),
('C', 2, 1),
('B', 3, 3);

Теперь давайте посмотрим на ваш код и приведем условия:

Вот ваш код:

 ORDER BY 
 CASE 
 WHEN @T='ABC' Then Val,Seq
 ELSE Sequence END
  • Если @T = 'ABC, тогда заказывайте по Val и Seq И НЕ заказывайте по Sequence.
  • Если @T <> 'ABC', то заказать Только с Sequence.

Если вы выполните этот запрос:

--You was trying--

DECLARE @T VARCHAR(3) = 'ABC'; --wil works only when @T <> ABC

SELECT *
FROM T
ORDER BY CASE WHEN @T='ABC' THEN Seq END, --Take INT
         CASE WHEN @T='ABC' THEN Val --Take Varchar
              ELSE Sequence -- Take INT
         END;

Будет выдано следующее сообщение об ошибке, если @T = 'ABC'

Msg 245 Уровень 16 Состояние 1 Строка 5

Ошибка преобразования при преобразовании значения varchar 'A' в тип данных int.

так же, как вы получаете

Преобразование не удалось при преобразовании значения nvarchar 'EX-02-60' в тип данных int.

Теперь, вот что вы хотите в соответствии с условиями, которые вы предоставляете:

--Fixes--

DECLARE @T VARCHAR(3) = '1'; --Try to change it to ABC too

SELECT *
FROM T
ORDER BY CASE WHEN @T='ABC' THEN Val END, --Take varchar
         CASE WHEN @T='ABC' THEN Seq -- Take INT
              ELSE Sequence -- Take INT
         END;
/*
 IF @T = ABC
 ORDER BY Val, Seq; NOT Sequence

 IF @T <> ABC
 ORDER BY ONLY Sequence
*/

А вот и Живая демоверсия

0 голосов
/ 09 января 2019

Я подозреваю, что вы ищете:

ORDER BY CASE @T WHEN 'ABC' THEN Val END,
         CASE @T WHEN 'ABC' THEN Seq END,
         [Sequence];

Чтобы понять, почему ваши попытки не сработали. Во-первых:

WHERE  Type = @T  ORDER BY 
 CASE 
 WHEN @T='ABC' Then Val,Seq
 ELSE Sequence END

A CASE - это выражение, которое возвращает скалярное значение. Здесь ваш WHEN пытался вернуть 2 значения. Это не разрешено.

 ORDER BY 
 CASE 
 WHEN @T='ABC' Then Convert(int,Val) 
 WHEN @T='ABC' Then Convert(nvarchar,Seq)
 ELSE Seq END

Поскольку CASE возвращает скалярное значение, он может возвращать только один тип данных. Выражение CASE использует приоритет типа данных, а int имеет более высокий приоритет, чем nvarchar, поэтому Seq будет неявно преобразовано в int; и я рискну догадаться, что это не удалось.

...