JPQL 子查询与参数相等

Posted

技术标签:

【中文标题】JPQL 子查询与参数相等【英文标题】:JPQL subquery equality to parameter 【发布时间】:2018-08-15 00:15:32 【问题描述】:

如何在 JPQL 中完成类似以下的操作?

SELECT item
  FROM Item item
  WHERE (
    SELECT tag.name, tag.color
    FROM Tag tag
    WHERE tag.item = item
    ORDER BY tag.name, tag.color
  ) = :tags

其中 :tags 是字符串对的列表(按名称和颜色排序),作为参数传入,通过 .getQuery().setParameter("tags", tags)

基本的想法是假设我有一组项目,每个项目都有 0+ 个相关的字符串和颜色标签,我希望找到任何具有一组特定名称/颜色标签的项目。

我基本上尝试使用上面显示的内容作为查询,但我得到了模糊的错误The right expression is not a valid expression。子查询似乎有问题。有任何想法吗?我并不关心这个解决方案与我上面的模板有多相似,只要它满足基本思想(并且可以动态指定目标标签集)。

【问题讨论】:

我认为您的查询甚至不会在任何版本的实际 SQL 上运行。如果子查询只选择一个列,您可以考虑以某种方式在 JPQL 中执行 WHERE IN 子句。但是由于子查询选择了两列,这在 JPQL 中可能不可行。 好的,假设我将两列连接成一个字符串。那能做到吗? 【参考方案1】:

好的,我想我已经或多或少找到了一种方法。

然而,它假设/要求,给定一个项目 X,任何标签名称最多只能在 X 上出现一次。可能可以修改该方法以允许完全重复的标签,但我不需要那个,所以我没有试图弄清楚。

SELECT item 
  FROM Item item 
  WHERE ( 
    SELECT COUNT(tag1) 
    FROM Tag tag1
    WHERE tag1.item = item 
    AND CONCAT(tag1.name, ',', tag1.color) IN :tags 
  ) = :tagCount 
  AND ( 
    SELECT COUNT(tag2) 
    FROM Tag tag2
    WHERE tag2.item = item 
  ) = :tagCount 
  AND ( 
    SELECT COUNT(DISTINCT tag3.name) 
    FROM Tag tag3 
    WHERE tag3.item = item 
  ) = :tagCount 

【讨论】:

以上是关于JPQL 子查询与参数相等的主要内容,如果未能解决你的问题,请参考以下文章

无法在 FROM 子句中使用子查询编写 JPQL 查询 - Spring Data Jpa - Hibernate

无法在 FROM 子句中使用子查询编写 JPQL 查询 - Spring Data Jpa - Hibernate

JPA JPQL - 如果不使用子对象(没有主键/外键关系)并且可以删除,则返回的查询

在 JPA 的 SQL 查询中的 FROM 语句中包含子查询

在 JPQL 中转换 NOT IN SELECT 查询

为啥在本机查询 Hibernate 延迟加载的子实体中?