[英]SQL Parametrized order by for a custom column name not working
I have a Procedure that sorts data according to provided sorting field and sorting direction.我有一个根据提供的排序字段和排序方向对数据进行排序的过程。 I had to add new sorting order for a field that is a combination of other two columns, but when I try to sort by the new column name I get an error.我必须为由其他两列组合而成的字段添加新的排序顺序,但当我尝试按新列名排序时出现错误。 Is there any workaround for this?有什么解决方法吗?
SELECT CONCAT(COALESCE([FirstName] + ' ',''), COALESCE([LastName],'')) as PatientName FROM [dbo].[patient]
order by
CASE WHEN @SortOrder = 'ASC' THEN
CASE @SortField
WHEN 'PatientName' THEN PatientName
WHEN 'OtherExistingColumn' THEN OtherExistingColumn
END
END ASC,
CASE WHEN @SortOrder = 'DESC' THEN
CASE @SortField
WHEN 'PatientName' THEN PatientName
WHEN 'OtherExistingColumn' THEN OtherExistingColumn
END
END DESC
I know there is a way to order columns according to their select numeration (order by 1), but for a procedure with 60+ fields being selected this definitely is not an option.我知道有一种方法可以根据 select 编号(按 1 排序)对列进行排序,但是对于选择了 60 多个字段的过程,这绝对不是一个选项。
Try with a subquery:尝试使用子查询:
SELECT *
FROM (SELECT CONCAT(COALESCE([FirstName] + ' ',''), COALESCE([LastName],'')) as PatientName, 0 as OtherExistingColumn FROM [dbo].[patient]) AS Data
order by
CASE WHEN @SortOrder = 'ASC' THEN
CASE @SortField
WHEN 'PatientName' THEN PatientName
WHEN 'OtherExistingColumn' THEN OtherExistingColumn
END
END ASC,
CASE WHEN @SortOrder = 'DESC' THEN
CASE @SortField
WHEN 'PatientName' THEN PatientName
WHEN 'OtherExistingColumn' THEN OtherExistingColumn
END
END DESC
Remember: CASE
expressions really are expressions .请记住: CASE
表达式确实是表达式。 They are not like if
statements for choosing which code to run.它们不像用于选择要运行的代码的if
语句。 Instead, they always have a single value as the result.相反,它们总是有一个单一的值作为结果。 Therefore you can't use them to do something like choose between an ASC
or DESC
branch.因此,您不能使用它们来执行诸如在ASC
或DESC
分支之间进行选择之类的操作。
Instead, if you have numeric data you could decide to multiply (or not) by -1:相反,如果您有数字数据,您可以决定乘以(或不乘以)-1:
ORDER BY
CASE @SortField
WHEN 'PatientName' THEN PatientName
WHEN 'OtherExistingColumn' THEN OtherExistingColumn
END * CASE WHEN @SortOrder = 'DESC' THEN -1 ELSE 1 END
If it's not numeric data, you need both expressions in the ORDER BY, where one of them uses the same value for everything (the existing code does this, but less-efficiently):如果它不是数字数据,则需要 ORDER BY 中的两个表达式,其中一个对所有内容使用相同的值(现有代码这样做,但效率较低):
ORDER BY
CASE WHEN @SortOrder <> 'ASC' THEN NULL
WHEN @SortField = 'PatientName' THEN PatientName
WHEN @SortField = 'OtherExistingColumn' THEN OtherExistingColumn
END ASC,
CASE WHEN @SortOrder <> 'DESC' THEN NULL
WHEN @SortField = 'PatientName' THEN PatientName
WHEN @SortField = 'OtherExistingColumn' THEN OtherExistingColumn
END DESC
Additionally, because these really are expressions this will only work if the columns in question use compatible types.此外,因为这些确实是表达式,所以只有当相关列使用兼容类型时才有效。 CASE expressions don't always work based on constant variables. CASE 表达式并不总是基于常量变量工作。 They have to allow for selecting one branch for one row, and a different branch for the next row, so they can fail if the column types don't agree.他们必须允许为一行选择一个分支,为下一行选择一个不同的分支,因此如果列类型不一致,它们可能会失败。
Finally, both options can really hurt performance, since the database can no longer predict, for example, that the value will always follow an index on something like the PatientName
column.最后,这两个选项都会真正损害性能,因为数据库无法再预测,例如,该值将始终遵循诸如PatientName
列之类的索引。 Instead of walking an index to create the result set, it really will need to build and sort the set in memory.不是遍历索引来创建结果集,它实际上需要在 memory 中构建和排序集合。
Therefore you're likely to get MUCH better performance handling a dynamic sort like this in the client code or reporting tool.因此,在客户端代码或报告工具中处理像这样的动态排序时,您可能会获得更好的性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.