Existe-t-il un équivalent MySQL de la clause WITH dans Oracle?
Existe-t-il un équivalent MySQL de la clause WITH dans Oracle?
Réponses:
Il n'y a pas. À moins que (jusqu'à ce que) on le développe (MySQL est open-source, tout le monde peut y contribuer.)
Le WITH
mot clé SQL ANSI / ISO est utilisé pour définir les expressions de table communes (CTE) et simplifie les requêtes complexes avec une ou plusieurs références imbriquées. Il est disponible dans Oracle, Postgres, SQL-Server, DB2 mais pas dans MySQL.
La requête finale peut avoir des références (généralement dans la FROM
clause mais elles peuvent se trouver dans n'importe quelle autre partie) à n'importe laquelle des expressions de table courantes, une ou plusieurs fois. La requête peut être écrite (sans CTE) dans MySQL à l'aide de tables dérivées mais les références doivent être faites à plusieurs reprises.
Exemple d'une requête idiote montrant toutes les personnes nées dans les années 50 et au mois de juillet et le nombre de toutes les personnes nées la même année:
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 ;
Dans MySQL, cela pourrait s'écrire:
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 ;
Notez la duplication de code pour la table dérivée a
. Dans les requêtes plus complexes, le code devrait être écrit plusieurs fois.
Cela fonctionnera mais c'est dommage que cela ne fournisse pas l'avantage d'utiliser la clause WITH, c'est-à-dire de ne pas exécuter la même requête plusieurs fois (avec des requêtes complexes, cela pourrait être vraiment lent et très exigeant pour le moteur de base de données; je l'ai souffert) .
Je suggérerais d' insérer chaque SELECT défini dans la clause WITH d'origine dans sa propre table temporaire et de les utiliser dans la requête . Dans MySQL, la table temporaire se supprimera une fois la session utilisateur terminée.
ÉDITER:
Je viens de voir cette réponse dans un fil similaire qui expose clairement les 3 solutions de contournement avec MySQL :
/programming//a/1382618/2906290
et un exemple de procédure MySQL qui crée et supprime les tables temporaires au cas où vous continueriez votre session et voudriez libérer ces ressources (je l'utiliserais juste comme exemple de syntaxe): /programming//a/ 5553145/2906290