java - 如何获取结果集中WHERE条件求值的结果?

标签 java sql mysql

问题

我有这样的查询:

select a.id from a join b on ( a.id = b.my_a ) join ....
where 
    ( /* complex and expensive conditional */ )
    AND 
       (( /* conditional #1 */ ) 
        OR ( /* conditional #2 */ )
        OR ( /* conditional #3 */))

我希望查询返回如下内容:

select a.id, conditional_1_eval_value, conditional_2_eval_value, conditional_3_eval_value from a join b on ( a.id = b.my_a ) join ....
where 
    ( /* complex and expensive conditional */ )
    AND 
       (( /* conditional #1 */ ) 
        OR ( /* conditional #2 */ ) 
        OR ( /* conditional #3 */))

其中 conditional_1_eval_valueconditional_2_eval_valueconditional_3_eval_value 设置为 TRUE、FALSE、NULL。 NULL 表示条件未被评估。

所以结果集可能是:

1, FALSE, NULL, TRUE ( condition_1, condition_3 were evaluate, condition_2 was not)
2, NULL, TRUE, TRUE ( condition_2, condition_3 were evaluate, condition_1 was not)
3, TRUE, FALSE, FALSE (all were evaluated)

condition_1condition_2condition_3 本身很复杂,涉及相关子查询和分组。

编辑:

我想要完成什么?

我们需要记录导致行返回的条件。我们不需要知道返回该行的所有原因。因此在结果示例的第二行中,知道 conditional_2conditional_3 都为真就足够了。不知道 conditional_1 值是什么并不重要。

知道至少满足一个条件以及那个条件是什么就足够了。

非最佳解决方案

显然我可以用这样的 UNION 来做到这一点:

select a.id, TRUE, NULL, NULL from a join b on ( a.id = b.my_a ) join ....
where 
    ( /* complex and expensive conditional */ )
    AND 
       ( /* conditional #1 */ )
UNION
select a.id, NULL, TRUE, NULL from a join b on ( a.id = b.my_a ) join ....
where 
    ( /* complex and expensive conditional */ )
    AND 
        ( /* conditional #2 */ )
UNION
select a.id, NULL, NULL, TRUE from a join b on ( a.id = b.my_a ) join ....
where 
    ( /* complex and expensive conditional */ )
    AND 
        ( /* conditional #3 */)

但这意味着:

  1. 常见的“复杂且昂贵的条件”被评估 3 次。
  2. 即使另一个条件已经满足 OR,也会评估所有条件。
  3. 确保通用复杂查询的 3 个副本相同(可以通过在代码中构建 sql 并复制通用字符串来解决——但这意味着我会违反另一个内部标准,即所有 sql 都不是嵌入在 java 中但在 DBA 可见的 xml 文件中)

在 select 中使用 CASE 复制每个条件 1 到 3 可避免对常见条件求值 3 次。但是,条件 1-3 的复杂性使其可能无法实现。

在 FROM 子句中使用 select 会很尴尬并且可能无法实现,因为 FROM SELECT 不能是相关查询。我不确定我能否构造一个有用的非相关查询。

存储过程 会起作用。但是,这将首先出现这样的存储过程,并且会显着增加我们的部署复杂性。

在 java 代码中执行 conditional_1conditional_2conditional_3 评估。这就是我们目前正在做的它运行缓慢。当数据库设计用于过滤结果集时传输大量数据——不应该在 java 中这样做!

解决方案建议?

有人吗?

我还应该补充一点,我欢迎说这个问题无法解决的答案。知道问题无法解决将节省我尝试使用严格的 SQL 解决它的时间。

如果必须选择的话,我会倾向于学习 mysql 存储过程的样子。

因此,如果您想自愿提供 mysql 存储过程是什么样子的,那就太好了。

最佳答案

要实现您的目标,为什么不对复杂条件使用存储函数?

这将导致选择语句如下:


select func1(arg1, arg2, ...), func2(arg1, arg2, ...), rest_of_select_columns 
from table1, table2
where (complex1 logic) 
OR func1(arg1, arg2, ....) = 1 /* return to give true */ 
OR func2(arg1, arg2, ....) = 1 

注意事项:

  1. SQL 不支持 boolean 数据类型,因此函数的结果为 true、false 是不可能的。因此,返回值 0,1。
  2. 根据您的 mySQL 版本,您可以使函数具有确定性,这可能会带来一些性能改进。

关于java - 如何获取结果集中WHERE条件求值的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1051343/

相关文章:

java - 驱动程序 :com. mysql.jdbc.Driver@2b7374f8 为 URL 返回 null

java - 计算由阶乘产生的数字的尾随零

sql - 使用 where 子句将 hive 数据输出到 csv

mysql - 从字符串中提取mysql中的数据

java - 不断收到 Illegal start of type 错误,我该如何纠正此问题并继续前进?

java - AtomicReference<ArrayList> 困难和备选方案

mysql 多行查询

java - 方法 createArrayOf 的 mysql JDBC 驱动程序出错

php - 在 php 中读取 json 层次结构

mysql - 查询将字段数据复制到另一个表