CASE
是产生单个值的表达式。它不能像您在其他语言中那样用于控制流,或者您可以尝试使用IF
. 您也不能IF
在查询中使用。
以下分别处理每种情况。如果条件不匹配,则该表达式的结果为 NULL,在任何排序中都将被忽略。所以这些子句的顺序无关紧要,因为只有所有条件都为真的那些才会被观察到:
ORDER BY
CASE WHEN @SortColumn = 'Type' AND @SortDir = 'DESC' THEN Type END DESC,
CASE WHEN @SortColumn = 'Name' AND @SortDir = 'DESC' THEN Name END DESC,
CASE WHEN @SortColumn = 'Type' AND @SortDir = 'ASC' THEN Type END,
CASE WHEN @SortColumn = 'Name' AND @SortDir = 'ASC' THEN Name END;
这些可能可以组合起来,但我不知道数据类型,所以这可能是最安全的。如果数据类型相同,则:
ORDER BY
CASE WHEN @SortDir = 'DESC' THEN
CASE WHEN @SortColumn = 'Type' THEN Type ELSE Name END
END DESC,
CASE WHEN @SortDir = 'ASC' THEN
CASE WHEN @SortColumn = 'Type' THEN Type ELSE Name END
END;
您无法进一步崩溃,因为您无法在一个表达式中进行条件ASC
与比较。DESC
但是您可以通过其他方式进行简化,例如以下查询将产生与上述相同的结果,即使在某些情况下 order by 将尝试执行(例如)ORDER BY Type DESC, Type DESC
-我不确定优化器是否将其简化为冗余但它应该折叠为单个排序运算符(需要时 - 有时此查询可能会根据用于满足查询的索引产生固有的排序)。
ORDER BY
CASE WHEN @SortColumn = 'Type' AND @SortDir = 'DESC' THEN Type END DESC,
CASE WHEN @SortColumn = 'Name' AND @SortDir = 'DESC' THEN Name END DESC,
CASE WHEN @SortColumn = 'Type' THEN Type END,
CASE WHEN @SortColumn = 'Name' THEN Name END;
...或者...
ORDER BY
CASE WHEN @SortDir = 'DESC' THEN
CASE WHEN @SortColumn = 'Type' THEN Type ELSE Name END
END DESC,
CASE WHEN @SortColumn = 'Type' THEN Type ELSE Name END;
您还可以考虑动态 SQL,因为如果这变得更复杂,这里有很多维护。
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SELECT ... ORDER BY ' + @SortColumn + ' ' + @SortDir;
PRINT @sql;
-- EXEC sp_executesql @sql;
当然这可能会引入其他问题(其余查询的可维护性,计划缓存膨胀......)