JPQL 的 INNER JOIN 问题(即使 SQL 请求正在运行)
Posted
技术标签:
【中文标题】JPQL 的 INNER JOIN 问题(即使 SQL 请求正在运行)【英文标题】:INNER JOIN issue with JPQL (even if the SQL request is working) 【发布时间】:2018-12-05 03:25:01 【问题描述】:“bonjour à tous”(大家好)
我来自这个线程: How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?
这个人正在做我项目中需要的几乎所有事情。 事实上,我正在尝试做一些类似 Git 的事情:检索上一个版本中的所有实例。 目前,我有一个表“UM”,具有这些属性:
int id(主键,自动生成) 字符串名称(可重复) int 版本(1、2、3、[...]) 字符串 fmr [其他属性,本例未使用]我在 SQL 中也有这个请求(运行良好并检索到想要的结果):
SELECT * FROM agrid.um AS u INNER JOIN
(SELECT u2.name, max(u2.version) AS MaxVersion, u2.fmr
FROM agrid.um AS u2 WHERE u2.fmr = 'CZ2ABVIMG0000' GROUP BY u2.name, u2.fmr) umVersion
ON u.name = umVersion.name AND u.version = umVersion.MaxVersion
WHERE u.fmr = 'ABCDE';
但是当我尝试在 JPQL 中做同样的事情时,我遇到了一些“JOIN”错误:
TypedQuery<UmEty> q = getManager().getEntityManager().createQuery(
"SELECT u FROM UmEty u INNER JOIN"
+ " (SELECT u2.name, max(u2.version) AS MaxVersion, u2.fmr "
+ " FROM UmEty u2 WHERE u2.fmr = :fmr GROUP BY u2.name, u2.fmr) umVersion"
+ " ON u.name = umVersion.name AND u.version = umVersion.MaxVersion WHERE u.fmr = :fmr", UmEty.class);
q.setParameter("fmr", fmr);
return q.getResultList();
以下例外:
Exception Description: Syntax error parsing
[SELECT u FROM UmEty u INNER JOIN (SELECT u2.name, max(u2.version)
AS MaxVersion, u2.fmr
FROM UmEty u2 WHERE u2.fmr = :fmr GROUP BY u2.name, u2.fmr) umVersion
ON u.name = umVersion.name
AND u.version = umVersion.MaxVersion WHERE u.fmr = :fmr].
[33, 147] The join association path is not a valid expression.
我也尝试过简单地使用“JOIN”而不是“INNER JOIN”,以及其他一些测试(删除“WHERE”子句,...),但我总是抛出这个异常。 我对 JPQL 不是很熟悉,而且我已经阅读过 Objectdb 上的“INNER JOIN”主题(==> https://www.objectdb.com/java/jpa/query/jpql/from)。但即使有这些信息,我也无法成功请求
谁能告诉我为什么我的 SQL 请求翻译成 JPQL 不能正常工作?
提前致谢:)
【问题讨论】:
不是问题,就像这个问题,之前问过 问题是:如何将此 SQL 请求转换为 JPQL 请求?为什么我有“加入”问题? 检查JPA: JOIN in JPQL 感谢您的帮助。但我已经尝试只使用“JOIN”和 ObjectDB 页面中列出的所有内容。但仍然没有工作:/ SQL 比 JPQL 强大得多 - 只有很小的 SQL 语言子集可以直接转换为像 JPQL 这样的混淆层。 【参考方案1】:要在 JPQL 中进行连接,您的对象图中必须直接依赖于要连接的实体。
这个例子来自规范本身:
SELECT c FROM Customer c JOIN c.orders o WHERE c.status = 1
其中Customer
是通过customer.orders
列表对象与Order
实体建立关系的实体。
您可以在Java Persistence Spec 的第 4.4.5 章中阅读有关联接的更多信息
编辑:
您可能希望重写查询以符合以下格式:
select * from agrid.um u
where u.fmr = 'ABCDE' and not exists
(select * from agrid.um u2 where u.name = u2.name and u.version < u2.version)
;
【讨论】:
好的,我明白了,但这不是我的“情况”。我只想在同一张表上工作,并通过预先选择的表(第二个 SELECT 子句)进行 JOIN。有可能吗? afaik 如果没有在实体模型中声明的显式关系,您将无法执行该查询。但是您可以翻译您的查询以使用 EXISTS 条件。 好吧,对不起,如果我错了,但是使用 jpql,您不能创建子选择查询(使用 where 和 having 子句除外) 嗨。有人已经对我说过了,但我已经在另一个(更简单的)案例中做到了。所以这不是这里的问题:/ 我已经编辑了我的答案,以使我对使用 EXISTS 的评论更加清晰。如果您想要的只是该表中条目的最大版本。以上是关于JPQL 的 INNER JOIN 问题(即使 SQL 请求正在运行)的主要内容,如果未能解决你的问题,请参考以下文章
SQL SERVER LEFT JOIN, INNER JOIN, RIGHT JOIN
left joinright join和inner join
left joinright join和inner join
SQL表连接查询(inner join(join)full joinleft joinright join)
SQL的JOIN语法解析(inner join, left join, right join, full outer join的区别)