MySQL equivalente de WITH en Oracle


Respuestas:


16

No hay. A menos que (hasta) uno lo desarrolle (MySQL es de código abierto, cualquiera puede contribuir).

La WITHpalabra 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 FROMclá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.


Para evitar la repetición (duplicación de código), ¿no sería mejor usar variables y tablas temporales?
Pacerier

No me preocuparía por la duplicación de código, pero ciertamente consideraría y probaría una versión con tablas temporales, por razones de rendimiento.
ypercubeᵀᴹ

1
¿Por qué dice que no se preocuparía por la duplicación de código? Esto es completamente desordenado y no  SECO .
Pacerier

1
@Pacerier DRY no siempre es relevante con el código DB.
JNK

1
@Pacerier No me sorprendería si no fuera así. Los motores de base de datos deben hacer conjeturas informadas sobre lo que funcionará mejor y al mismo tiempo garantizar que se obtengan resultados correctos. Las tablas temporales en general están bien, pero DRY conduce a un rendimiento terrible en las bases de datos en otros aspectos, como las funciones definidas por el usuario.
JNK

2

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 :

  • Tablas temporales
  • Tablas derivadas
  • vistas en línea (efectivamente lo que representa la cláusula WITH, son intercambiables)

/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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.