Mezclar JOIN implícitas y explícitas

Resuelto Chase Seibert asked hace 15 años • 3 respuestas

Tengo un problema con Hibernate que genera SQL no válido. Específicamente, mezclar y combinar uniones implícitas y explícitas. Esto parece ser un error abierto .

Sin embargo, no estoy seguro de por qué este SQL no es válido. Se me ocurrió un pequeño ejemplo de juguete que genera la misma excepción de sintaxis.

Esquema

CREATE TABLE Employee (
    employeeID INT,
    name VARCHAR(255),
    managerEmployeeID INT   
)

Datos

INSERT INTO Employee (employeeID, name) VALUES (1, 'Gary')
INSERT INTO Employee (employeeID, name, managerEmployeeID) VALUES (2, 'Bob', 1)

SQL de trabajo

Ambas consultas funcionan. Me doy cuenta de que hay un producto cartesiano; eso es intencional.

UNIRSE explícitamente:

SELECT e1.name,
       e2.name,
       e1Manager.name
  FROM Employee e1
 CROSS JOIN Employee e2
 INNER JOIN Employee e1Manager
    ON e1.managerEmployeeID = e1Manager.employeeID

UNIRSE implícitamente:

SELECT e1.name,
       e2.name,
       e1Manager.name
  FROM Employee e1,
       Employee e2,
       Employee e1Manager
 WHERE e1.managerEmployeeID = e1Manager.employeeID

SQL no válido

Esta consulta NO funciona en MSSQL 2000/2008 o MySQL:

SELECT e1.name, 
       e2.name, 
       e1Manager.name
  FROM Employee e1,
       Employee e2
 INNER JOIN Employee e1Manager 
    ON e1.managerEmployeeID = e1Manager.employeeID

En MS2000, aparece el error:

El prefijo de columna 'e1' no coincide con el nombre de una tabla o el nombre de alias utilizado en la consulta.

En MySQL, el error es:

Columna desconocida 'e1.managerEmployeeID' en la 'cláusula on'.

Preguntas)

  1. ¿Por qué esta sintaxis no es válida?
  2. Bonificación: ¿Hay alguna forma de obligar a Hibernate a utilizar solo JOINs explícitos?

Chase Seibert avatar Apr 18 '09 01:04 Chase Seibert
Aceptado

Da como resultado un error porque, según el estándar SQL, la JOINpalabra clave tiene mayor prioridad que la coma. El problema es que los alias de tablas no se pueden utilizar hasta que la tabla correspondiente haya sido evaluada en la FROMcláusula.

Entonces, cuando haces referencia e1en tu JOIN...ONexpresión, e1aún no existe.

Espere mientras investigo sobre Hibernate y averigüe si puede convencerlo para que lo utilice JOINen todos los casos.


Mmm. Todo en Hibernate.org parece redirigir a jboss.org. Así que no hay forma de leer la documentación HQL en línea en este momento. Estoy seguro de que eventualmente descubrirán su nombre.

Bill Karwin avatar Apr 17 '2009 18:04 Bill Karwin

Esto podría estar un poco fuera de tema, porque no tiene nada que ver con la hibernación, pero el comentario de Bill Karwin realmente me abrió los ojos. En lugar de escribir primero la unión implícita, primero debe realizar la unión explícita. Esta sintaxis es especialmente interesante si tiene varias combinaciones implícitas.

Consulte el siguiente ejemplo en MS SQL. No todos los contactos tienen un código de país definido, pero todos los contactos tienen un atributo val que se buscará en la tabla Tbl. Entonces la solución intuitiva no funcionará:

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

En su lugar, es posible que desee utilizar la siguiente sintaxis:

SELECT * FROM 
contacts LEFT OUTER JOIN country ON CtryCod = country.CtryCod, 
Tbl
WHERE val = Tbl.val
Damian Vogel avatar Mar 22 '2013 13:03 Damian Vogel