Sql 混合隐式连接和显式连接

Sql 混合隐式连接和显式连接,sql,hibernate,join,cartesian-product,cross-join,Sql,Hibernate,Join,Cartesian Product,Cross Join,我在Hibernate生成无效SQL时遇到问题。具体来说,混合和匹配隐式和显式联接。这似乎是一个问题 但是,我不确定为什么这是无效的SQL。我提出了一个小玩具示例,它生成了相同的语法异常 模式 数据 工作SQL 这两个查询都有效。我意识到有一个笛卡尔积;那是故意的 显式联接: 隐式联接: 无效SQL 此查询在MSSQL 2000/2008或MySQL上不起作用: SELECT e1.name, e2.name, e1Manager.name FROM Empl

我在Hibernate生成无效SQL时遇到问题。具体来说,混合和匹配隐式和显式联接。这似乎是一个问题

但是,我不确定为什么这是无效的SQL。我提出了一个小玩具示例,它生成了相同的语法异常

模式 数据 工作SQL 这两个查询都有效。我意识到有一个笛卡尔积;那是故意的

显式联接:

隐式联接:

无效SQL 此查询在MSSQL 2000/2008或MySQL上不起作用:

SELECT e1.name, 
       e2.name, 
       e1Manager.name
  FROM Employee e1,
       Employee e2
 INNER JOIN Employee e1Manager 
    ON e1.managerEmployeeID = e1Manager.employeeID
在MS2000中,我得到一个错误:

列前缀“e1”不匹配 使用表名或别名 在查询中

在MySQL中,错误是:

未知列“e1.managerEmployeeID” 在“on子句”中

问题 为什么这个语法无效? 额外好处:有没有办法强制Hibernate只使用显式连接?
它会导致错误,因为根据SQL标准,JOIN关键字的优先级高于逗号。关键点在于,在FROM子句中计算相应的表之前,表别名不可用

所以,当您在表达式的JOIN…中引用e1时,e1还不存在

我正在研究Hibernate,请稍候,看看您是否能说服它在所有情况下都使用JOIN


嗯,Hibernate.org上的所有内容似乎都被重定向到jboss.org。所以现在没有办法在线阅读HQL文档。我相信他们最终会找到自己的名字的。

PostgreSQL也给出了一个错误:

ERROR:  invalid reference to FROM-clause entry for table "e1"
LINE 7:     ON e1.managerEmployeeID = e1Manager.employeeID;
               ^
HINT:  There is an entry for table "e1", but it cannot be referenced from this part of the query.
我认为问题在于,在这种情况下,当您连接两个表a和b e2和e1Manager时,您只能在ON子句中引用这两个表。因此,您可以在本ON子句中引用e2和e1Manager,但不能引用e1

我认为这是一种扩展,因此如果您有一个JOIN语句链,那么您可以在ON子句中引用同一链中的其他表,但不能交叉,。所以像'a在a.a_id=b.a_id上加入b在c.b_id=b.b_id和c.a_id=a.a_id上加入c这样的东西是允许的


您用于生成此SQL的HQL是什么?类似于从Employee e1、Employee e2中选择e1.name、e2.name、e1.manager.name之类的内容?

这可能有点离题,因为它与hibernate无关,但来自的评论确实让我大开眼界。您需要先进行显式连接,而不是先编写隐式连接。如果有多个隐式联接,则此语法尤其有趣

在MS SQL中检查以下示例。并非所有联系人都定义了国家代码,但所有联系人都有一个属性val,该属性将在表Tbl中查找。因此,直观的解决方案不起作用:

SELECT * FROM 
contacts, Tbl
LEFT OUTER JOIN country ON CtryCod = country.CtryCod 
WHERE val = Tbl.val
相反,您可能更希望使用以下语法:

SELECT * FROM 
contacts LEFT OUTER JOIN country ON CtryCod = country.CtryCod, 
Tbl
WHERE val = Tbl.val

从候选人a中选择a.id、a.category.id、a.category.name、a.owner,其中category和owner是关联。真正重要的是,如果您将所有者放在第一位,它会起作用,这是由于连接的幸运重新排序。基于问题的快速重现,您可能希望尝试不混合选择实体和属性:选择a.id、a.category、a.owner或a.id、a.category.id、a.category.name,a.owner.id-这两个选项都为我生成了有效的SQL,但是您的HQL生成了无效的SQL,正如您为我所说的,我通常只获取候选对象,让Hibernate根据需要自动加载类别和所有者。或者使用left-join-fetch急切地获取它们。这是否回答了您的问题?
SELECT e1.name, 
       e2.name, 
       e1Manager.name
  FROM Employee e1,
       Employee e2
 INNER JOIN Employee e1Manager 
    ON e1.managerEmployeeID = e1Manager.employeeID
ERROR:  invalid reference to FROM-clause entry for table "e1"
LINE 7:     ON e1.managerEmployeeID = e1Manager.employeeID;
               ^
HINT:  There is an entry for table "e1", but it cannot be referenced from this part of the query.
SELECT * FROM 
contacts, Tbl
LEFT OUTER JOIN country ON CtryCod = country.CtryCod 
WHERE val = Tbl.val
SELECT * FROM 
contacts LEFT OUTER JOIN country ON CtryCod = country.CtryCod, 
Tbl
WHERE val = Tbl.val