我的代码中有一些NativeQuery,看起来像这样,其中“stateValue”将被计算,可以是1或0:
SELECT
MAX(CASE
WHEN(? < t.someDate + interval '3 months' ) THEN 1
ELSE 0
END) AS stateValue
FROM
my_table t
ORDER BY
CASE WHEN LOWER(:sortColumn) = 'status' AND LOWER(:sortDirection) = 'asc' THEN stateValue END ASC,
CASE WHEN LOWER(:sortColumn) = 'status' AND LOWER(:sortDirection) = 'desc' THEN stateValue END DESC,
我想排序的“状态值”列,但如果我试图使用“状态值”在ORDER BY我得到错误
*“错误:列“statevalue”不存在”
有什么办法能把它修好吗?谢谢!
2条答案
按热度按时间zte4gxcn1#
您的问题中的查询有一列,这是一个聚合表达式,因此您将只得到1行。
假设您有更多的列作为分组依据,例如:
如果你不想在
ORDER BY
子句中重复完整的MAX(CASE ...)
表达式(这确实是个好主意),你可以使用CTE,就像@ahmed建议的那样:这可能有用,但我认为这很奇怪。奇怪的是,您使用了一种变通方法,使用参数值来完成标识符(排序列名)和关键字(
ASC
和DESC
)的工作。(* 详细示例如下... *)
当然,它可以工作,但它可能会使您的SQL变得不必要的复杂。我怀疑它在某些情况下也会混淆查询规划器。
我不确定您使用的是什么语言来构建这个查询,但您显然使用了SQL本身之外的东西(可能是Java/Hibernate)。
当你想把值传递到SQL查询中时,你确实应该总是使用查询参数,而不是连接字符串(以避免SQL注入),在这里,你可以在构建SQL查询时,在SQL查询外部测试排序列和排序顺序。
sortColumn
和sortOrder
不需要在SQL查询中作为值使用(并且您实际上正在将它们与当前构造的查询中的文字进行比较)。这里的主要区别是
sortDirection
和sortOrder
永远不会是或引用表或表达式中的任何值。相反,它们用于确定查询中需要使用哪些标识符和关键字(ASC
/DESC
)。当然,请确保不要将这些变量直接连接到查询字符串中(同样,为了避免SQL注入),但是使用外部代码使用 literals 在查询字符串中构建标识符并没有错。
详细示例:
基本上,你依赖于这样一个事实,
LOWER(:sortColumn) = 'status' AND LOWER(:sortDirection) = 'asc'
为假时,CASE WHEN LOWER(:sortColumn) = 'status' AND LOWER(:sortDirection) = 'asc' THEN stateValue END
是NULL
,CASE WHEN LOWER(:sortColumn) = 'status' AND LOWER(:sortDirection) = 'desc' THEN stateValue END DESC
假设你的例子看起来像这样:
扩展后,当
sortDirection
是asc
时,它看起来像这样:| 类别|m|案例|案例|
| - -----|- -----|- -----|- -----|
| 一个|十五|十五|(空)|
| B|二十五|二十五|(空)|
这里,使用了一阶表达式,而第二阶表达式中的所有值都为null,因此它是不相关的。
当
sortDirection
为desc
时| 类别|m|案例|案例|
| - -----|- -----|- -----|- -----|
| B|二十五|(空)|二十五|
| 一个|十五|(空)|十五|
这里,第一阶表达式中的值都是空的,因此在相同的级别处理,因此然后使用第二表达式中的值。
xqk2d5yq2#
不管你的查询返回什么(见@Bruno评论),你需要在一个子查询或cte中 Package 你的查询,考虑以下简化:
以下内容将引发错误(列“sd”不存在):
以下方法可行:
demo