Hibernate HQL 内部连接子选择
Hibernate HQL inner join subselect
我得到了以下 SQL,我想将其转换为有效的 HQL。这个问题是,不允许根据 docs 加入子查询。尽管这些是旧文档 (v3.3),但此部分似乎仍保留在 hibernate 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
子句
我认为您的 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 table,只需通过 table。但是我需要更多地了解您的实际用例,以及您使用的 RDBMS。
在@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
以前我是 运行 这个本地 SQL 查询 ResultTransformer
:
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
,结果也是一致的。我会进一步评估哪些结果更合适,但如果新结果正确,我不会感到惊讶。
我得到了以下 SQL,我想将其转换为有效的 HQL。这个问题是,不允许根据 docs 加入子查询。尽管这些是旧文档 (v3.3),但此部分似乎仍保留在 hibernate 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
子句
我认为您的 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 table,只需通过 table。但是我需要更多地了解您的实际用例,以及您使用的 RDBMS。
在@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
以前我是 运行 这个本地 SQL 查询 ResultTransformer
:
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
,结果也是一致的。我会进一步评估哪些结果更合适,但如果新结果正确,我不会感到惊讶。