为什么没有嵌套CASE语句不起作用?

时间:2018-01-02 09:02:51

标签: sql-server-2008 sql-server-2008-r2 sql-order-by

我需要根据列选择动态地对结果进行排序。我知道下面只有第一个查询有效,第二个查询失败。但是我无法理解它失败的原因,根据我对@SortDirection值的理解,它应该给ASC或DESC,它将附加到返回列名的早期CASE。你能解释一下它失败的原因吗?

create table EmpData
(
EmpID int identity,
FName varchar(20),
LName varchar(20),
Email varchar(30),
City varchar(20),
DOB date
)
GO
INSERT INTO EmpData values ('Mark','Smith','Mark.s@email.com','London','02-Jun-1980')
INSERT INTO EmpData values ('Mark','Marsh','Mark.m@email.com','Paris','02-Jul-1981')
INSERT INTO EmpData values ('Steve','Elgar','Steve.e@email.com','Canada','12-Jun-1980')
INSERT INTO EmpData values ('Michael','Jones','Michael.j@email.com','France','22-Jan-1980')
GO
----------QUERY 1--------
DECLARE @SortByColumn varchar(20)='City',
@SortDirection varchar(5)='ASC'
SELECT EmpID,FName AS FirstName, LName AS LastName, Email, City, DOB as 'Date-Of-Birth'
FROM EmpData
ORDER BY
    CASE @SortDirection WHEN 'ASC' THEN
        CASE @SortByColumn
            WHEN 'FirstName' THEN FName
            WHEN 'LastName' THEN LName
            WHEN 'Email' THEN Email
            WHEN 'City' THEN City
            ELSE ''
        END
    END,
    CASE @SortDirection WHEN 'DESC' THEN
        CASE @SortByColumn
            WHEN 'FirstName' THEN FName
            WHEN 'LastName' THEN LName
            WHEN 'Email' THEN Email
            WHEN 'City' THEN City
            ELSE ''
        END
    END DESC
GO
----------QUERY 2--------
DECLARE @SortByColumn varchar(20)='City',
@SortDirection varchar(5)='ASC'
SELECT EmpID,FName AS FirstName, LName AS LastName, Email, City, DOB as 'Date-Of-Birth'
FROM EmpData
ORDER BY
        CASE @SortByColumn
            WHEN 'FirstName' THEN FName
            WHEN 'LastName' THEN LName
            WHEN 'Email' THEN Email
            WHEN 'City' THEN City
            ELSE ''
        END
        CASE @SortDirection
            WHEN 'DESC' THEN DESC
            ELSE ASC
        END

2 个答案:

答案 0 :(得分:0)

试试这个

DECLARE @SortByColumn varchar(20)='City',
@SortDirection varchar(5)='asc'
;WITH CTE
AS
(
SELECT 
Seq1 = ROW_NUMBER() OVER(ORDER BY
        CASE @SortByColumn
            WHEN 'FirstName' THEN FName
            WHEN 'LastName' THEN LName
            WHEN 'Email' THEN Email
            WHEN 'City' THEN City
            ELSE ''
        END ASC),
Seq2 = ROW_NUMBER() OVER(ORDER BY
        CASE @SortByColumn
            WHEN 'FirstName' THEN FName
            WHEN 'LastName' THEN LName
            WHEN 'Email' THEN Email
            WHEN 'City' THEN City
            ELSE ''
        END DESC),
EmpID,FName AS FirstName, LName AS LastName, Email, City, DOB as 'Date-Of-Birth'
FROM EmpData
  )
  SELECT
    *
    FROM CTE
    ORDER BY CASE @SortDirection WHEN 'DESC' THEN Seq2 ELSE Seq1 END

DEMO

答案 1 :(得分:0)

在这种情况下最好使用动态SQL

Declare @sql nvarchar(max)
declare @orderby nvarchar(100) = ' ORDER BY '
DECLARE @SortByColumn varchar(20) = 'City'
declare @SortDirection varchar(5) = 'ASC'

set @sql = '
SELECT EmpID,FName AS FirstName, LName AS LastName, Email, City, DOB as ''Date-Of-Birth''
FROM EmpData
' +
CASE @SortByColumn
    WHEN 'FirstName' THEN @orderby + ' FName ' + @SortDirection
    WHEN 'LastName' THEN @orderby + ' LName ' + @SortDirection
    WHEN 'Email' THEN @orderby + ' Email ' + @SortDirection
    WHEN 'City' THEN @orderby + ' City ' + @SortDirection
    ELSE ''
END

exec sp_executesql @sql

由于ASC或DESC是SQL子句,我们不能在CASE语句中使用它们