¿Hay un equivalente MySQL de la cláusula WITH en Oracle?
¿Hay un equivalente MySQL de la cláusula WITH en Oracle?
Respuestas:
No hay. A menos que (hasta) uno lo desarrolle (MySQL es de código abierto, cualquiera puede contribuir).
La WITH
palabra clave ANSI / ISO SQL se utiliza para definir Expresiones de tabla comunes (CTE) y simplifica las consultas complejas con una o varias referencias anidadas. Está disponible en Oracle, Postgres, SQL-Server, DB2 pero no en MySQL.
La consulta final puede tener referencias (generalmente en la FROM
cláusula pero podrían estar en cualquier otra parte) a cualquiera de las expresiones de tabla comunes, una o más veces. La consulta se puede escribir (sin CTE) en MySQL utilizando tablas derivadas, pero las referencias deben hacerse repetidamente.
Ejemplo de una consulta tonta que muestra a todas las personas nacidas en los años 50 y en el mes de julio y el número de todas las personas nacidas en el mismo año:
WITH a AS
( SELECT name, birthdate, YEAR(birthdate) AS birthyear
FROM persons
WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01'
)
, b AS
( SELECT birthyear, COUNT(*) AS cnt
FROM a
GROUP BY birthyear
)
SELECT a.name, a.birthdate, b.cnt AS number_of_births
FROM a JOIN b
ON a.birthyear = b.birthyear
WHERE MONTH(a.birthdate) = 7 ;
En MySQL, podría escribirse como:
SELECT a.name, a.birthdate, b.cnt AS number_of_births
FROM
( SELECT name, birthdate, YEAR(birthdate) AS birthyear
FROM persons
WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01'
) AS a
JOIN
( SELECT birthyear, COUNT(*) AS cnt
FROM
( SELECT name, birthdate, YEAR(birthdate) AS birthyear
FROM persons
WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01'
) AS aa
GROUP BY birthyear
) AS b
ON a.birthyear = b.birthyear
WHERE MONTH(a.birthdate) = 7 ;
Observe la duplicación de código para la tabla derivada a
. En consultas más complejas, el código debería escribirse varias veces.
Eso funcionará, pero es una pena que no proporcione la ventaja de usar la cláusula WITH, es decir, no ejecutar la misma consulta varias veces (con consultas complejas podría ser realmente lento y muy exigente para el motor de la base de datos; lo sufrí) .
Sugeriría insertar cada SELECT definido en la cláusula WITH original en su propia tabla temporal y usarlos dentro de la consulta . En MySQL, la tabla temporal se soltará una vez que finalice la sesión del usuario.
EDITAR:
Acabo de ver esta respuesta en un hilo similar que expone claramente las 3 soluciones con MySQL :
/programming//a/1382618/2906290
y un ejemplo del procedimiento MySQL que crea y elimina las tablas temporales en caso de que continúe con su sesión y desee liberar esos recursos (lo usaría solo como un ejemplo de la sintaxis): /programming//a/ 5553145/2906290