以下查询仅匹配select子查询中找到的第一个值,即使所有值都匹配SELECT p FROM Profile p WHERE p.id IN (SELECT u.group FROM User u WHERE u.id = ?1)
子查询返回逗号分隔的列表,如:1,2,3
。查询应返回所有三个子查询选择结果的匹配项。谁知道什么可能是错的?感谢。
答案 0 :(得分:2)
IN
子句在JPQL和SQL中都不会以这种方式工作。
(..)
内的值不是“以逗号分隔的字符串”,而是值列表。此列表可以字面指定为逗号分隔的字符串,也可以由子查询生成,如您的情况。也就是说,查询中的条件为p.id IN ("1,2,3")
(而非p.id IN (1,2,3)
),因此不会产生所需的结果。
因此,您无法使用查询语言(JPQL或SQL)的强大功能来针对非规范化架构编写查询(您的列包含值列表,因此它违反了1NF)。如果Profile
和User
之间存在多对多关系,请将其表示为与中间联接表的多对多关系。
答案 1 :(得分:1)
虽然IN
运算符支持与子查询的结果进行比较,但您正在做的事情无法正常工作(我很惊讶您甚至得到了一个结果)。在进一步讨论之前,让我引用JPA 2.0规范:
4.6.9在表达式中
使用的语法 比较运算符[NOT] IN in a 条件表达式如下:
in_expression ::= {state_field_path_expression | type_discriminator} [NOT] IN { ( in_item {, in_item}* ) | (subquery) | collection_valued_input_parameter } in_item ::= literal | single_valued_input_parameterstate_field_path_expression 必须有一个字符串,数字,日期, 时间,时间戳或枚举值。
文字和/或输入参数 值必须像一样 抽象模式类型 类型中的 state_field_path_expression 。 (见4.12节)。
子查询的结果必须是 喜欢相同的抽象模式类型 类型中的 state_field_path_expression 。子查询在中讨论 第4.6.16节。
示例:
o.country IN (’UK’, ’US’, ’France’)
UK
为真,Peru
为false, 并且相当于表达式(o.country = ’UK’) OR (o.country = ’US’) OR (o.country = ’ France’)
。o.country NOT IN (’UK’, ’US’, ’France’)
的
UK
为false,为true 对于Peru
,并且相当于 表达NOT ((o.country = ’UK’) OR (o.country = ’US’) OR (o.country = ’France’))
。必须至少有一个元素 以逗号分隔的列表定义
IN
的值集 表达如果是a的值 IN或NOT IN表达式中的 state_field_path_expression 或 in_item 为
NULL
或未知, 表达式的值是未知的。请注意使用集合值 输入参数意味着a 静态查询无法预编译。
所以,首先,p.id
与subselect的返回类型不匹配(实际上是一个“次要”问题)。
其次,这是一个主要问题和误解,你的查询不会产生类似的结果(使用“伪代码”):
p.id IN (1, 2, 3)
这是你想要的 - 但是在
p.id IN (’1,2,3’)
这显然不是你想要的,也不行。
我唯一的建议是:对数据库进行normarlize。