Sql 具有多列的动态按选择排序
当ORDER BY基于CASE语句时,选择多个ORDER BY列的正确MS SQL语法是什么 以下内容适用于单列,但我需要按多列排序:Sql 具有多列的动态按选择排序,sql,sql-server,Sql,Sql Server,当ORDER BY基于CASE语句时,选择多个ORDER BY列的正确MS SQL语法是什么 以下内容适用于单列,但我需要按多列排序: SELECT * FROM Products ORDER BY CASE WHEN @SortIndex = 1 THEN Price END ASC, CASE WHEN @SortIndex = 2 THEN Price DESC, Title ASC END <-- problem line 你可以试试这个 SELECT * FROM Produ
SELECT * FROM Products
ORDER BY
CASE WHEN @SortIndex = 1 THEN Price END ASC,
CASE WHEN @SortIndex = 2 THEN Price DESC, Title ASC END <-- problem line
你可以试试这个
SELECT * FROM Products
ORDER BY
CASE WHEN @SortIndex = 1 THEN Price END ASC,
CASE WHEN @SortIndex = 2 THEN Price END DESC,
CASE WHEN @SortIndex = 2 THEN Title END ASC
做这个。。。和你的表演说再见。不幸的是,最好的解决方案是使用动态sql。尝试使用动态sql,以降低对服务器性能的影响-假设@SortIndex 1和2处只有2个值。如果没有,请使用更多条件扩展If
If @SortIndex = 1
BEGIN
SELECT * FROM Products ORDER BY Price ASC
END
ELSE
BEGIN
SELECT * FROM Products ORDER BY Price DESC, TITLE ASC
END
@布拉德。帕维尔提出了以下建议,我想
DECLARE @query VARCHAR(MAX)
SET @query = 'SELECT * FROM Products
ORDER BY
'
IF (@SortIndex = 1)
SET @query =@query + ' Price ASC '
ELSE IF (@SortIndex = 2)
SET @query =@query + ' Price DESC, Title ASC '
sp_executesql @query
为什么您认为动态sql不适合复杂的存储过程?这些正是您应该使用动态SQL的地方,因为它可以帮助降低复杂性并解决诸如参数嗅探之类的问题。我同意动态sql有其缺点,但我建议您至少尝试一下,如果它适合您的话。您可以重写以下内容:
ORDER BY
CASE WHEN @SortIndex = 1 THEN Price END ASC,
CASE WHEN @SortIndex = 2 THEN Price DESC, Title ASC END
作为
这会将添加的排序列添加到所有案例中,但在我的情况下,这正是我想要的
您也可以这样做,例如:
CASE WHEN @SortIndex = 1 THEN Price END ASC,Title ASC,
CASE WHEN @SortIndex = 2 THEN Price DESC END
想详细说明一下吗?我在一个相当复杂的存储过程中实际应用了它,在这个过程中,动态SQL是不可能的。在我使用MSSQL的12年经验中,我遇到了多个ocation,这些构造产生了糟糕的计划。这并不是说它本身不好,只是我发现它不可靠,即今天运行良好的查询可能会在未来4个月产生糟糕的计划我在这里嗅到参数:。。此解决方案实际上可能会引入参数嗅探,假设这是一个存储过程,@SortIndex是存储过程的一个参数。为了便于讨论,我们假设还有另一个条件——如果@SortIndex=3,那么只按平铺排序,假设有一个价格指数和一个标题指数。现在,如果您第一次使用@SortIndex=1调用存储过程,SQL server将创建一个exec计划,该计划将使用价格索引。再次调用存储过程时,无论@SortTitle的值是多少,SQL server都将使用与以前相同的计划。因此,如果@SortTitle=3,它仍将使用价格索引,即使它在这里没有用处,我从未假设这是一个存储过程。如果它是一个简单的SQL语句,具有变量声明和变量属性值,那么查询应该有一个良好的执行计划,这取决于它将使用哪个叶。用户没有说这是一个只有一个参数的存储过程;如果真的是这样的话,考虑到为每个组合检索的行数,可以启用或禁用参数嗅探。谢谢您的建议。我将尝试这种方法。查询越复杂,尤其是那些具有多个输入、多个排序选择等的可怕列表过程,您从动态SQL获得的结果就越可靠。我这里唯一的建议是保护您的动态查询免受注入攻击。对于我的特殊问题,我使用了Price END ASC,而不是Price END DESC,因为我们必须从数据库中的同一列加载排序列。所以为了使它干净,我们用空格分隔每一列,并用负号代替DESCI投票赞成yrushka的答案。这是一个有效的选择。但在我的例子中,我使用了上面的方法,用户有12个可能的列进行排序,因此这种样式/选项看起来更实用。如果我添加查询语句本身非常复杂的话,我上面的评论会更有意义。在这种情况下,用不同的orderby条款重复整个station 12次是不切实际的。
CASE WHEN @SortIndex = 1 THEN Price END ASC,Title ASC,
CASE WHEN @SortIndex = 2 THEN Price DESC END