Hibernate HQL内部联接子选择

时间:2019-02-19 16:03:16

标签: java hibernate hql

我得到了以下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子句

2 个答案:

答案 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,结果也是一致的。我会评估哪些结果更合适,但如果新结果正确,我也不会感到惊讶。