我得到了以下SQL,希望将其转换为有效的HQL。这样做的问题是,不允许每个docs对其子查询进行联接。即使这些是旧版文档(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
我想出了这个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
尝试执行此HQL查询会导致此异常
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 169
提示(
处的INNER JOIN (SELECT
。
是否可以在HQL中加入子查询?如果不是,那么与HQL的SQL取得相同结果的最佳方法是什么?
我不能将inner join on <sub-query>
转换为允许子查询的实际where
子句
答案 0 :(得分:2)
我认为您的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
这应该更容易转换为HQL,甚至可能更正确,因为您的原始查询似乎在自连接行之间创建了不需要的笛卡尔积。
也许有一种更好的方法来查询SQL,而无需通过单次通过表就自动加入Foo表。但是我需要更多地了解您的实际用例,以及正在使用的RDBMS。
答案 1 :(得分:0)
借助@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
以前,我使用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
两个查询之间的结果实际上存在细微的差异,但是并不一致。在此情况下,我的意思是一致的,并不是每个结果date
的结果都会有所不同,只是某些结果会有所不同。同样对于提供的参数:name
,结果也是一致的。我会评估哪些结果更合适,但如果新结果正确,我也不会感到惊讶。