首页 > 解决方案 > 如何在 Spring Data 中使用 SQL 根据某些参数有选择地与某些表相交?

问题描述

我在数据库中有n个表,每个表对应n个参数。我必须找到对应参数为真的所有这些表之间的值的交集。

必需的行为

所需的行为是这样的:
表 1:

commonValue1
value1
commonValue2
value2

表 2:

value3
commonValue1
value4
commonValue2

表3:

value5
value6
commonValue1
commonValue2

表 4:

value7
value8
commonValue1
commonValue2

查询的预期结果何时param1 = true, param2 = true, param3 = true, param4 = true

commonValue1
commonValue2

实际查询结果:

(empty)

尝试过的解决方案

我的方法是这样的:

@Query("""
   SELECT * FROM table1 WHERE :param1 = true
      INTERSECT
   SELECT * FROM table2 WHERE :param2 = true
      INTERSECT
   SELECT * FROM table3 WHERE :param3 = true
      INTERSECT 
   SELECT * FROM table4 WHERE :param4 = true
""")
fun getIntersection(
  @Param("param1") param1: Boolean, 
  @Param("param2") param2: Boolean, 
  @Param("param3") param3: Boolean, 
  @Param("param4") param4: Boolean
): List<ReturnType>

但这不起作用。有什么解决办法吗?

标签: sqlspringspring-bootspring-data

解决方案


我不认为有一个简单的方法可以做到这一点。但一种方法是:

SELECT val1, val2, common1, common2
FROM ((SELECT t1.*, 1 as which FROM table1 t1 WHERE :param1 = true)
      UNION ALL
      (SELECT t2.*, 2 FROM table2 t2 WHERE :param2 = true)
      UNION ALL
      (SELECT t3.*, 3 FROM table3 t3 WHERE :param3 = true)
      UNION ALL
      (SELECT t4.*, 4 FROM table3 t4 WHERE :param3 = true)
     ) t
GROUP BY val1, val2, common1, common2
HAVING COUNT(DISTINCT which) = ( (CASE WHEN :param1 = true THEN 1 ELSE 0) +
                                 (CASE WHEN :param2 = true THEN 1 ELSE 0) +
                                 (CASE WHEN :param3 = true THEN 1 ELSE 0) +
                                 (CASE WHEN :param4 = true THEN 1 ELSE 0)
                              );

这不是最有效的方法。您的查询的问题是子查询不返回任何行,除非:paramis true。因此路口是空的。

更好的方法是INTERSECT在应用程序中构造您需要的查询。生成的查询没有:param值——它只有需要的表。


推荐阅读