Java JPA/JPQL连接子选择/子查询
我很难将一些简单的SQL语句转换为JPQL,因为JPQL不支持使用的子查询 有人能给我一个提示,如何使用JPQL或JPA2标准API实现相同的结果 给定(简化假数据以证明问题): 预期结果:Java JPA/JPQL连接子选择/子查询,java,jpa,join,subquery,jpql,Java,Jpa,Join,Subquery,Jpql,我很难将一些简单的SQL语句转换为JPQL,因为JPQL不支持使用的子查询 有人能给我一个提示,如何使用JPQL或JPA2标准API实现相同的结果 给定(简化假数据以证明问题): 预期结果: | name | number | |--------|---------------| | John | +49-123-11111 | | Mike | | | Paul | | | Walter | +49-123-
| name | number |
|--------|---------------|
| John | +49-123-11111 |
| Mike | |
| Paul | |
| Walter | +49-123-44444 |
爪哇:
试试这个:
选择person.name、phone.number
从个人
左连接person.phones作为电话
其中phone.type为NULL或phone.type=“MOBILE”
首先,根据一些JPA提供商(如EclipseLink和TopLink)在FROM
条款中的子选择,尽管JPA规范中没有定义
在JPA2.1中,您可以使用左连接和ON
:
SELECT person.name, phone.number
FROM Person person
LEFT JOIN person.phones AS phone ON phone.person = person AND phone.type = 'MOBILE'
在JPA 2.1之前,您可以使用case
表达式:
SELECT person.name,
CASE WHEN (phone.type = 'MOBILE') THEN phone.number ELSE '' END
FROM Person person
LEFT JOIN person.phones AS phone
但这只会擦除所有非移动电话号码-因此,一个人的每个电话号码都会有一行,即使他/她有多个不是移动电话号码的电话号码
如果JPA提供程序正确地呈现了这些内容(Hibernate在大多数情况下都会这样做),则可以使用数据库的列表聚合功能(如Oracle中的listag
)。如果一个人可以拥有多个手机号码,那么这对于前两个选项也是有意义的
SELECT person.name, phone.number
FROM Person AS person LEFT JOIN person.phones AS phone
ON phone.type = 'MOBILE'
您还可以将ON
关键字替换为特定于hibernate的:
SELECT person.name, phone.number
FROM Person AS person LEFT JOIN person.phones AS phone
WITH phone.type = 'MOBILE'
这也行不通。WHERE子句在加入电话表后删除行。因此,只有工作号码的迈克将被解雇。
SELECT person.name,
CASE WHEN (phone.type = 'MOBILE') THEN phone.number ELSE '' END
FROM Person person
LEFT JOIN person.phones AS phone
SELECT person.name, phone.number
FROM Person AS person LEFT JOIN person.phones AS phone
ON phone.type = 'MOBILE'
SELECT person.name, phone.number
FROM Person AS person LEFT JOIN person.phones AS phone
WITH phone.type = 'MOBILE'