Trabalho com MySQL há algum tempo, porém ainda estou aprendendo as melhores maneiras de usá-lo.
Para praticar, escrevi uma consulta para obter a categoria de filme mais destacada para cada ator no banco de dados de exemplo sakila que podemos obter com o workbench para MySQL. O resultado fica assim:
Eu recebo o resultado com a seguinte consulta. No entanto, tive que repetir a mesma consulta duas vezes, uma vez na from
parte da consulta externa e uma segunda vez na where
parte de uma subconsulta.
select `MCPA`.`first_name` ,`MCPA`.`last_name`,
group_concat(`MCPA`.`category`) as `most_featured_categories`
from
(
SELECT AC.first_name as `first_name` ,AC.last_name as `last_name` ,
CA.`name` as `category` ,
count( distinct FI.film_id ) as `number_of_movies` ,
count( distinct FI.film_id ) /
fNumber_Of_Films_Per_Actor (AC.first_name, AC.last_name) * 100
as `percentage_of_movies_done`
from actor as AC
inner join film_actor as FIAC ON AC.actor_id = FIAC.actor_id
inner join film as FI ON FIAC.film_id = FI.film_id
inner join film_category as FICA ON FI.film_id = FICA.film_id
inner join category as CA ON FICA.category_id = CA.category_id
group by AC.first_name, AC.last_name, CA.`name`
) as `MCPA`
where `MCPA`.`number_of_movies` =
(
SELECT max(`SubMCPA`.`number_of_movies`)
from
(
SELECT AC.first_name as `first_name`, AC.last_name as `last_name`,
CA.`name` as `category` ,
count( distinct FI.film_id ) as `number_of_movies` ,
count( distinct FI.film_id ) /
fNumber_Of_Films_Per_Actor (AC.first_name,
AC.last_name
) * 100
as `percentage_of_movies_done`
from actor as AC
inner join film_actor as FIAC ON AC.actor_id = FIAC.actor_id
inner join film as FI ON FIAC.film_id = FI.film_id
inner join film_category as FICA ON FI.film_id = FICA.film_id
inner join category as CA
ON FICA.category_id = CA.category_id
group by AC.first_name, AC.last_name, CA.`name`
) as `SubMCPA`
where 1=1
and `MCPA`.`first_name` = `SubMCPA`.`first_name`
and `MCPA`.`last_name` = `SubMCPA`.`last_name`
)
group by `MCPA`.`first_name`, `MCPA`.`last_name` ;
eu tinha tentado usar
select max(`SubMCPA`.`number_of_movies`)
from `MCPA` as `SubMCPA`
where 1=1
and `MCPA`.`first_name` = `SubMCPA`.`first_name`
and `MCPA`.`last_name` = `SubMCPA`.`last_name`
Mas não funcionou; parece que o workbench não reconhece a tabela derivada e exige que eu a redefina.
Eu tenho alguma outra maneira de evitar digitar o código
(
select AC.first_name as `first_name`
,AC.last_name as `last_name`
,CA.`name` as `category`
,count( distinct FI.film_id ) as `number_of_movies`
,count( distinct FI.film_id ) /
fNumber_Of_Films_Per_Actor (AC.first_name, AC.last_name) * 100
as `percentage_of_movies_done`
from actor as AC
inner join film_actor as FIAC
on AC.actor_id = FIAC.actor_id
inner join film as FI
on FIAC.film_id = FI.film_id
inner join film_category as FICA
on FI.film_id = FICA.film_id
inner join category as CA
on FICA.category_id = CA.category_id
group by AC.first_name, AC.last_name, CA.`name`
) as
duas vezes?
** Eu tentei evitá-lo primeiro criando uma tabela e depois referenciando-a, no entanto, talvez haja alguma outra maneira?
Além disso, parece que ter feito tudo em uma consulta aumenta o desempenho.
Qualquer conselho seria apreciado, espero que minha pergunta tenha sido clara, evitei descrever toda a estrutura do banco de dados para evitar uma pergunta muito tediosa.
Algo assim lhe dá a resposta?:
Para um possível desempenho adicional, veja minhas dicas em muitas: muitas tabelas .