Existe um equivalente MySQL da cláusula WITH no Oracle?
Existe um equivalente MySQL da cláusula WITH no Oracle?
Respostas:
Não há. A menos que (até) a desenvolva (o MySQL é de código aberto, qualquer pessoa pode contribuir).
A WITH
palavra-chave ANSI / ISO SQL é usada para definir CTEs (Common Table Expressions) e simplifica consultas complexas com uma ou várias referências aninhadas. Está disponível no Oracle, Postgres, SQL-Server, DB2, mas não no MySQL.
A consulta final pode ter referências (geralmente na FROM
cláusula, mas podem estar em qualquer outra parte) a qualquer uma das expressões comuns da tabela, uma ou mais vezes. A consulta pode ser escrita (sem CTEs) no MySQL usando tabelas derivadas, mas as referências precisam ser feitas repetidamente.
Exemplo de uma pergunta boba mostrando todas as pessoas nascidas nos anos 50 e no mês de julho e o número de todas as pessoas nascidas no mesmo ano:
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 ;
No MySQL, poderia ser escrito 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 a duplicação de código para a tabela derivada a
. Em consultas mais complexas, o código teria que ser escrito várias vezes.
Isso funcionará, mas é uma pena que não forneça a vantagem de usar a cláusula WITH, que não é executar a mesma consulta várias vezes (com consultas complexas pode ser realmente lenta e muito exigente para o mecanismo de banco de dados; eu sofri) .
Eu sugeriria inserir cada SELECT definido na cláusula WITH original em sua própria tabela temporária e usá-los dentro da consulta . No MySQL, a tabela temporária se soltará assim que a sessão do usuário terminar.
EDITAR:
Acabei de ver esta resposta em um tópico semelhante que expõe claramente as três soluções alternativas com o MySQL :
/programming//a/1382618/2906290
e um exemplo de procedimento MySQL que cria e elimina as tabelas temporárias , caso você continue com sua sessão e queira liberar esses recursos (eu o usaria apenas como exemplo da sintaxe): /programming//a/ 5553145/2906290