SQL: оператор case в порядке по предложению

http://msdn.microsoft.com/en-us/library/ms181765.aspx

Я вижу sql ниже ссылку сверху:

SELECT BusinessEntityID, SalariedFlag
FROM HumanResources.Employee
ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID END DESC
    ,CASE WHEN SalariedFlag = 0 THEN BusinessEntityID END;
GO

Вот один результат, который я получаю:

BusinessEntityID,SalariedFlag

7,1

5,1

3,1

1,1

2,0

4,0

6,0

8,0

Может ли кто-нибудь объяснить, почему записи с одинаковым salariedFlag находятся рядом друг с другом и почему кусок salariedFlag = 1 выше фрагмента salariedFlag = 0?

Ответы на вопрос(4)

BusinessEntityID когда флаг1, а затем разрешить связи путемBusinessEntityID когда флаг0, Это потому что первыйCASE выражение оценивается какnull когдаSalariedFlag не является1так что все записи с флагом0 перемещены после записи с флагом1.

Решение Вопроса

что может быть немного более очевидным:

ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID ELSE null END DESC
        ,CASE WHEN SalariedFlag = 0 THEN BusinessEntityID ELSE null END;

Таким образом, первое поле сортировки - это BusinessEntityID, когда SalariedFlag = 1 или ноль.
Это сгруппирует все строки, где SalariedFlag = 0, так как все они имеют нулевое поле первой сортировки.
Строки с SalariedFlag = 1 будут отсортированы по BusinessEntityID. Похоже, что нули сортируются последними в порядке убывания, поэтому все SalariedFlag! = 1 идут последними.

Это основной вид, для вторичного вида происходит почти то же самое:
Все строки, в которых SalariedFlag = 0, будут отсортированы по BusinessEntityID. Поскольку все их основные поля сортировки были нулевыми, они в конечном итоге будут упорядочены по BusinessEntityID.

И все строки, где SalariedFlag! = 0 будут сгруппированы вместе с нулевым вторичным порядком. Если бы эти строки имели SalariedFlag = 1, то они были бы уже отсортированы по первому порядку.

Если SalariedFlag может быть только 0 или 1, то этот вид можно (немного) упростить до:

ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID END DESC
        , BusinessEntityID;
 Ziyang Zhang18 мая 2012 г., 02:44
Отличный ответ, спасибо !!

которые вы выбираете обратно. Это должно помочь уточнить, по каким значениям происходит сортировка.

 18 мая 2012 г., 16:50
SalariedFlag - это не то, на что я ссылаюсь. Попробуйте включить CASE SalariedFlag, КОГДА 1 THEN BusinessEntityID END, CASE КОГДА SalariedFlag = 0 THEN BusinessEntityID END
 Ziyang Zhang18 мая 2012 г., 02:23
: SalariedFlag уже в списке выбора

почему он так отсортирован, включив условия CASE WHEN в предложение SELECT:

SELECT BusinessEntityID, SalariedFlag,

CASE SalariedFlag WHEN 1 THEN BusinessEntityID END AS A,
CASE WHEN SalariedFlag = 0 THEN BusinessEntityID END AS B

FROM Employee
ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID END DESC
    ,CASE WHEN SalariedFlag = 0 THEN BusinessEntityID END;

Выход:

BUSINESSENTITYID  SALARIEDFLAG      A                 B
7                 1                 7                 (null)
5                 1                 5                 (null)
3                 1                 3                 (null)
1                 1                 1                 (null)
2                 0                 (null)            2
4                 0                 (null)            4
6                 0                 (null)            6
8                 0                 (null)            8

Причина, по которой SalariedFlag 0 остается вместе, заключается в том, что все они попадают (посмотрите на столбец A) в значение null, было бы совсем другое дело, если бы было другое значение для SalariedFlag, скажем, номер 2, и этот запрос больше не будет работать, с таким же флагом не может быть рядом друг с другом.

NULL сортировать первым, если вы укажете DESC, он будет сортироваться последним.

Живой тест:http://www.sqlfiddle.com/#!3/1b849/13

Признавая, что запрос CASE, КОГДА THEN использует BusinessEntityID целочисленного типа, вы можете выполнить следующий запрос для достижения того же эффекта; и поскольку он использует SalariedFlag в качестве разделителя, следующий запросmight будьте быстрее, так как вы не используете условные выражения в ORDER BY. Вы можете просто переключить SalariedFlag и отсортировать по нему:

-- just to visualize things up
SELECT BusinessEntityID, SalariedFlag,

    A = BusinessEntityID * SalariedFlag,
    B = BusinessEntityID * (SalariedFlag ^ 1) 

FROM Employee
ORDER BY A DESC, B 

-- in actual you do this:

SELECT BusinessEntityID, SalariedFlag

FROM Employee
ORDER BY BusinessEntityID * SalariedFlag DESC, BusinessEntityID * (SalariedFlag ^ 1) 

Учитывая эти данные:

CREATE TABLE [Employee]
    ([BusinessEntityID] int, [SalariedFlag] int);

INSERT INTO [Employee]
    ([BusinessEntityID], [SalariedFlag])
VALUES
    (10, 1),
    (5, 1),
    (9, 1),
    (1, 1),
    (2, 0),
    (7, 0),
    (6, 0),
    (8, 0);

Это вывод:

BUSINESSENTITYID  SALARIEDFLAG      A                 B
10                1                 10                0
9                 1                 9                 0
5                 1                 5                 0
1                 1                 1                 0
2                 0                 0                 2
6                 0                 0                 6
7                 0                 0                 7
8                 0                 0                 8

Живой тест:http://www.sqlfiddle.com/#!3/e65ac/2

Ваш ответ на вопрос