[英]Hibernate HQL inner join subselect
I got the following SQL which I wanted to transform into valid HQL. 我得到了以下要转换为有效HQL的SQL。 The issue with this is, that its not permitted to join on a sub-query per the docs .
问题是,每个docs都不允许其加入子查询。 Even though these are old docs (v3.3) this section still seems to still hold in hibernate 5.3.
即使这些是旧版文档(v3.3),本节仍然在休眠5.3中仍然有效。
SELECT f.date,
f.name,
SUM(f.seats)
FROM Foo f
INNER JOIN (SELECT fl.date,
fl.start + fl.end AS code
FROM Foo fl
WHERE fl.date >= (SELECT MAX(earliestDate)
FROM Bar)
AND fl.name = :name) fl
ON f.start + f.end = code
AND f.date = fl.date
WHERE f.date >= ( SELECT MAX(earliestDate)
FROM Bar)
GROUP BY f.date,
f.name
ORDER BY f.date ASC,
SUM(f.seats) DESC
I came up with this HQL: 我想出了这个HQL:
SELECT NEW com.company.project.model.FooRepresentation( f.fooId.date,
f.fooId.name,
SUM(f.seats))
FROM Foo f
INNER JOIN (SELECT fl.fooId.date,
fl.fooId.start + fl.fooId.end AS code
FROM Foo fl
WHERE fl.fooId.date >= (SELECT MAX(earliestDate)
FROM FooConfig)
AND fl.fooId.name = :name) fl
ON f.fooId.start + f.fooId.end = code
AND f.fooId.date = fl.fooId.date
WHERE f.fooId.date >= ( SELECT MAX(earliestDate)
FROM FooConfig)
GROUP BY f.fooId.date,
f.fooId.name
ORDER BY f.fooId.date ASC,
SUM(f.seats) DESC
Trying to execute this HQL query, results in this exception 尝试执行此HQL查询会导致此异常
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 169
which hints to the (
at INNER JOIN (SELECT
. 提示
(
在INNER JOIN (SELECT
。
Is there a way to join on sub-queries within HQL? 是否可以在HQL中加入子查询? If not, what would be the best way to achieve the same results as the SQL with HQL?
如果不是,与HQL的SQL取得相同结果的最佳方法是什么?
I am not that good with converting the inner join on <sub-query>
to an actual where
clause where the sub-query is permitted 我不能将
inner join on <sub-query>
的inner join on <sub-query>
转换为允许子查询的实际where
子句
I think your SQL query can be rewritten to this: 我认为您的SQL查询可以改写为:
SELECT f.date, f.name, SUM(f.seats)
FROM Foo f
WHERE EXISTS (
SELECT 1
FROM Foo f1
WHERE f.start + f.end = f1.start + f1.end
AND f.date = f1.date
AND f1.date >= (SELECT MAX(earliestDate) FROM Bar)
AND f1.name = :name
)
AND f.date >= (SELECT MAX(earliestDate) FROM Bar)
GROUP BY f.date, f.name
ORDER BY f.date ASC, SUM(f.seats) DESC
This should be simpler to translate to HQL, and it might even be more correct, because your original query seems to create an unwanted cartesian product between the self joined rows. 转换为HQL应该更简单,甚至可能更正确,因为您的原始查询似乎在自连接行之间创建了不需要的笛卡尔积。
There's probably an even better way to query this in SQL, without self joining the Foo table, using a single pass through the table. 可能有一种更好的方法来查询SQL,而无需通过单次遍历表就自动加入Foo表。 But I'd need to know more about your real world use-case for that, and what RDBMS you're using.
但是我需要更多地了解您的实际用例,以及正在使用的RDBMS。
With the help of @LukasEder's answer, I created this HQL: 借助@LukasEder的答案,我创建了以下HQL:
SELECT NEW com.company.project.model.FooRepresentation( f.fooId.date,
f.fooId.name,
SUM(f.seats) )
FROM Foo f
WHERE EXISTS ( SELECT 1
FROM Foo f1
WHERE f.fooId.start + f.fooId.end = f1.fooId.start + f1.fooId.end
AND f.fooId.date = f1.fooId.date
AND f1.fooId.date >= ( SELECT MAX(earliestDate)
FROM FooConfig)
AND f1.fooId.name = :name )
AND f.fooId.date >= ( SELECT MAX(earliestDate)
FROM FooConfig)
GROUP BY f.fooId.date,
f.fooId.name
ORDER BY f.fooId.date ASC,
SUM(f.seats) DESC
Previously I was running this native SQL query with a ResultTransformer
: 以前,我使用
ResultTransformer
运行此本机SQL查询:
SELECT f.date,
f.name,
SUM(f.seats)
FROM Foo f
INNER JOIN (SELECT fl.date,
fl.start + fl.end AS code
FROM Foo fl
WHERE fl.date >= ( SELECT MAX(earliestDate)
FROM FooConfig)
AND fl.name = :name) fl
ON f.start + f.end = code
AND f.date = fl.date
WHERE f.date >= ( SELECT MAX(earliestDate)
FROM FooConfig)
GROUP BY f.date,
f.name
ORDER BY f.date ASC,
SUM(f.seats) DESC
there are actually slight differences with the results between the two queries, but those are not consistent. 实际上,两个查询的结果之间存在细微的差异,但是并不一致。 With consistent I mean in this case, that its not for every possible
date
that the results differ, just for some. 在此情况下,我的意思是一致的,并不是在每个可能的
date
结果都不同,而只是在某些方面。 Also for the provided parameter :name
, the results are consistent. 同样对于提供的参数
:name
,结果也是一致的。 I will evaluate more on which results are more fitting, but I wouldn't be surprised if the new ones are correct. 我将对哪些结果更合适进行更多的评估,但是如果新结果正确,我不会感到惊讶。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.