使用多个CASE子句对空值的最后一个语法排序

时间:2018-06-21 10:19:50

标签: sql sql-server

我有一个非常简单的ORDER BY子句,它基于几个变量进行排序:

ORDER BY 
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'asc' THEN emp.FirstName END asc,
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'desc' THEN emp.FirstName END desc

我遇到的问题是,当emp.FirstName为空时,它在排序中排在第一位。为了解决这个问题,我尝试引入另一种情况,但是我似乎无法使语法适用于多个情况。

这是ORDER BY的当前版本:

ORDER BY 
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'asc' THEN CASE WHEN emp.FirstName = '' THEN 2 ELSE 1 END, emp.FirstName asc,
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'desc' THEN CASE WHEN emp.FirstName = '' THEN 2 ELSE 1 END, emp.FirstName desc

如上所述,这在第一个END上存在语法错误。

6 个答案:

答案 0 :(得分:1)

可能最简单的方法是替换一个值。合理的解决方案是:

ORDER BY 
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'asc' THEN COALESCE(emp.FirstName, 'ZZZ') END asc,
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'desc' THEN COALESCE(emp.FirstName, 'ZZZ') END desc

'ZZZ'更好的值是'~',因为这是一个很大的ASCII值。

注意:如果您使用不同的排序规则,则可能需要其他值。

答案 1 :(得分:1)

您也可以尝试这个。

ORDER BY 
    CASE WHEN @sortCol = 'OwnerName' AND emp.FirstName IS NULL THEN 1 ELSE 0 END ASC, 
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'asc' THEN emp.FirstName END asc,
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'desc' THEN emp.FirstName END desc

答案 2 :(得分:0)

您似乎也在混合数据类型。内部CASE返回一个int,而outervarchar子句中返回一个ELSE。我认为,可以通过使用ISNULL解决该问题。但是,由于缺乏样本和预期结果,这是一个猜测

ORDER BY 
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'asc' THEN ISNULL(emp.FirstName,'zzzzzzz') END asc,
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'desc' THEN ISNULL(emp.FirstName,'zzzzzzzz') END desc

答案 3 :(得分:0)

也许reverse使脚本更有趣

ORDER BY 
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'asc' THEN emp.FirstName 
    else reverse(emp.FirstName) END asc

答案 4 :(得分:0)

我假设您想获得一个用于排序后备字段的字段?


如果不为null,则使用OwnerName,否则使用名字

enter image description here

你去了:)

复制粘贴示例

SET @sortCol = 'OwnerName', @sortDir = 'DESC'; 

Select
    tmp.*
FROM (
    SELECT
        NULL as OwnerName,
        '2' as FirstName
    UNION SELECT 
       '5' as OwnerName,
        '4' as FirstName
    UNION SELECT 
       '1' as OwnerName,
        '6' as FirstName
    ) tmp
ORDER BY
    CASE WHEN
        @sortCol = 'OwnerName' AND @sortDir = 'ASC'
    THEN
        CASE WHEN
            OwnerName IS NOT NULL
        THEN
            OwnerName
        ELSE
            FirstName
        END
    END ASC,
    CASE WHEN
        @sortCol = 'OwnerName' AND @sortDir = 'DESC'
    THEN
        CASE WHEN
            OwnerName IS NOT NULL
        THEN
            OwnerName 
        ELSE
            FirstName       
        END 
    END DESC

答案 5 :(得分:0)

您在这里:

CREATE TABLE T(
    FirstName VARCHAR(45)
    );

DECLARE @sortCol VARCHAR(45) = 'OwnerName';
DECLARE @sortDir VARCHAR(5) = 'asc';

INSERT INTO T VALUES
('One'),
('Two'),
(''),
(NULL),
('Three'),
('Four');

SELECT *
FROM T
ORDER BY 
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'asc' THEN IIF(FirstName = '' OR FirstName IS NULL, 'ZZZZZZZZ', FirstName) END asc,
    CASE WHEN @sortCol = 'OwnerName' AND @sortDir = 'desc' THEN IIF(FirstName = '' OR FirstName IS NULL, 'ZZZZZZZZ', FirstName) END desc;

您说的是:我遇到的问题是,当emp.FirstName为空时,它在排序中排在首位,我认为您最好检查一下EmptyString('')或NULL

Demo