简体   繁体   English

SQL 自定义列名称的参数化排序依据不起作用

[英]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.因此,您不能使用它们来执行诸如在ASCDESC分支之间进行选择之类的操作。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM