当前位置: 首页 > 知识库问答 >
问题:

HibernateHQL内部联接子选择

伏星汉
2023-03-14

我得到了下面的SQL,我想将其转换为有效的HQL。这方面的问题是,不允许根据文档加入子查询。尽管这些是旧文档(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

这将提示 内部连接 (选择.

有没有办法加入HQL中的子查询?如果不是,那么获得与具有HQL的SQL相同的结果的最佳方法是什么?

我不擅长转换内部连接


共有2个答案

宁修永
2023-03-14

借助@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

以前,我使用ResultTransform运行这个本机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

实际上,这两个查询的结果略有不同,但并不一致。我的意思是,在这种情况下,并不是所有可能的结果都不同,只是有些不同。此外,对于提供的参数:name,结果是一致的。我会更多地评估哪些结果更合适,但如果新的结果是正确的,我不会感到惊讶。

闾丘朗
2023-03-14

我想你的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。

 类似资料:
  • 我想从两个select查询的内部联接中选择两列。我编写了一个连接三个表的查询,从结果中我只希望得到两列。但是我的查询显示错误。我使用的是oracle sql Developer。 我只想要名字和姓氏,但我得到了这样的错误:

  • 我想从short_name(国家名称)、name(州表)或region_name的任何可用数据中选择post_id。对region_name而不是short_name(国家名称),name(州表)执行以下查询,结果为真。 请告诉我,我哪里弄错了!

  • 如何在Hibernate中编写此SQL查询?我想使用Hibernate创建查询,而不是创建数据库。 我在SQLServer2008中创建了实体类, 我尝试用多种方法构建工作选择查询,但仍然不起作用。 也许实体有问题?

  • 问题内容: 这个问题已经在这里有了答案 : INNER JOIN ON vs WHERE子句 (12个答案) 7年前关闭。 我有两个选择连接SQL语句: 显然,它们的结果相同。但是它们之间没有任何区别,例如性能,可移植性。 问题答案: 一个区别是,第一个选项通过在where子句中表达联接条件来隐藏意图。 第二个选项,写出连接条件的条件对于阅读查询的用户来说更加清楚。它显示了查询的确切意图。 至于性

  • 问题内容: 我有一个数据表(AmenityData),该表的一列包含postalsectors,例如E14 7 我也有一个Excel电子表格,其中包含邮政区的列表,例如E14 我需要从AmenityData表中获取所有数据,该表中的邮政地区类似于邮政部门,例如WHERE [PostalDistricts] +’%’LIKE [PostalSector]。 我目前正在使用的代码不会出现错误,而是什么

  • 问题内容: 如何在Hibernate中编写此SQL查询?我想使用Hibernate创建查询,而不是创建数据库。 我在SQLServer2008中创建了实体类, 我试图以多种方式构建有效的选择查询,但仍然无法正常工作。 实体有问题吗? 问题答案: 连接只能在实体之间存在关联时使用。您的Employee实体不应将名称为,类型为的字段映射到列。它应该与Team实体具有ManyToOne关联,并映射为Jo