Eri*_*eid 6 stored-procedures order-by t-sql case
我试图CASE ORDER BY
在存储过程中使用 T-SQL,在其中我将 @OrderBy 参数作为 TINYINT 传递。
@Orderby = 1 Then Date column should be ASC
@Orderby = 2 Then Date column should be DESC
我的问题是:当我为该参数传递 2 时,如何让日期列对 desc 进行排序,并在同一个 CASE ORDER BY 语句中将字符串列按 asc 排序?
这就是我现在所拥有的 CASE ORDER BY
ORDER BY
CASE WHEN @OrderBy = 1 THEN CONVERT(NVARCHAR(30) , ccd.CertEndDate) + tp.LastName + tp.FirstName END ,
CASE WHEN @OrderBy = 2 THEN CONVERT(NVARCHAR(30) , ccd.CertEndDate) + tp.LastName + tp.FirstName END DESC
Run Code Online (Sandbox Code Playgroud)
此代码解析并返回一个结果集没有错误,但第二个 CASE ORDER BY 都是 DESC 排序顺序,当我更喜欢 ccd.CertEndDate DESC , tp.LastName ASC , tp.FirstName ASC
提前致谢。
再分解一下:
ORDER BY CASE WHEN @orderby = 1 THEN CONVERT(NVARCHAR(30) , ccd.CertEndDate) END ASC,
CASE WHEN @orderby = 2 THEN CONVERT(NVARCHAR(30) , ccd.CertEndDate) END DESC,
tp.lastname ASC,
tp.firstname ASC
Run Code Online (Sandbox Code Playgroud)
您只需要更改第一个字段的排序顺序,因此不要将其他字段包含在CASE
.
应该注意的是,我们不包括ELSE
for each CASE
,这意味着任何其他值都将返回NULL
并从ORDER BY
.
除了 JNK 的回答,您还可以考虑:
DECLARE @Example TABLE
(
first_name NVARCHAR(50) NOT NULL,
last_name NVARCHAR(50) NOT NULL,
cert_end_date DATE NOT NULL,
other_columns NCHAR(100) NOT NULL DEFAULT (N'')
UNIQUE (cert_end_date ASC, first_name, last_name),
UNIQUE (cert_end_date DESC, first_name, last_name)
)
INSERT @Example
(first_name, last_name, cert_end_date)
VALUES
('a', 'w', '2008-12-31'),
('b', 'x', '2009-12-31'),
('c', 'y', '2010-12-31'),
('d', 'z', '2011-12-31')
DECLARE
@order_date_ascending BIT = CONVERT(BIT, 'true')
-- 1. May require an explicit sort despite useful indexes
SELECT
e.first_name,
e.last_name,
e.cert_end_date
FROM @Example AS e
ORDER BY
CASE WHEN @order_date_ascending = 1 THEN e.cert_end_date END ASC,
CASE WHEN @order_date_ascending = 0 THEN e.cert_end_date END DESC,
e.first_name ASC,
e.last_name ASC
-- 2. Conditional statements
IF @order_date_ascending = CONVERT(BIT, 'true')
BEGIN
SELECT
e.first_name,
e.last_name,
e.cert_end_date
FROM @Example AS e
ORDER BY
e.cert_end_date ASC,
e.first_name ASC,
e.last_name ASC
END
ELSE IF @order_date_ascending = CONVERT(BIT, 'false')
BEGIN
SELECT
e.first_name,
e.last_name,
e.cert_end_date
FROM @Example AS e
ORDER BY
e.cert_end_date DESC,
e.first_name ASC,
e.last_name ASC
END
-- 3. Union All & Start-up Filters
SELECT * FROM
(
SELECT TOP (9223372036854775807)
e.first_name,
e.last_name,
e.cert_end_date
FROM @Example AS e
WHERE
@order_date_ascending = CONVERT(BIT, 'true')
ORDER BY
e.cert_end_date ASC,
e.first_name ASC,
e.last_name ASC
) AS sort_asc
UNION ALL
SELECT * FROM
(
SELECT TOP (9223372036854775807)
e.first_name,
e.last_name,
e.cert_end_date
FROM @Example AS e
WHERE
@order_date_ascending = CONVERT(BIT, 'false')
ORDER BY
e.cert_end_date DESC,
e.first_name ASC,
e.last_name ASC
) AS sort_desc
Run Code Online (Sandbox Code Playgroud)
如果发生语句级编译或使用OPTION (RECOMPILE)
查询提示强制发生,则第一种和第三种方法可以受益于 SQL Server 2008 SP1 CU5 上可用的参数嵌入优化。有关详细信息,请参阅此MSDN 博客条目。
第三种方法不需要每次都编译,因为计划中的过滤器操作符有一个启动表达式。每个过滤器下方的计划子树仅在条件评估为真时才执行。