Конвертировать выбор UNION в одиночный выбор с циклом в MySQL - PullRequest
0 голосов
/ 26 мая 2018

У меня есть этот уродливый код в MySQL 8.0.

(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Adventure'
        group by genre_name, actor_id 
        ORDER BY count(actor_id) DESC
        limit 3)        
UNION 
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Music'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Fantasy'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Romance'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Family'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Comedy'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Short'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Animation'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Action'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Horror'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Sci-Fi'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Thriller'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Crime'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Drama'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Documentary'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Musical'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Mystery'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='War'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Western'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Adult'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3)
UNION
(SELECT genre_name, actor_id, count(actor_id)
       FROM movie_has_genre, role, movie, genre
        where role.movie_id=movie.movie_id
        and movie_has_genre.movie_id=movie.movie_id
        and genre.genre_id=movie_has_genre.genre_id
        and genre_name='Film-Noir'
        group by genre_name, actor_id
        ORDER BY count(actor_id) DESC
        limit 3);

, и я хочу преобразовать его, чтобы сделать его более кратким.По сути, единственное, что меняется, - это условие genre_name.Можно найти 21 значение для этого условия: select genre_name from genre; Как я могу просмотреть 21 значение genre_name и вставить их в запрос select, постепенно создавая запрос UNION?Спасибо.

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

В MySQL (до 8.0) для этого можно использовать переменные:

select genre_name, actor_id, cnt
from (select genre_name, actor_id, cnt,
             (@rn := if(@g = genre_name, @rn + 1,
                        if(@g := genre_name, 1, 1)
                       )
             ) as rn
      from (select g.genre_name, r.actor_id, count(*) as cnt
            from movie m join
                 role r
                 on r.movie_id = m.movie_id join
                 movie_has_genre mhg
                 on mhg.movie_id = m.movie_id join
                 genre g
                 on g.genre_id = mhg.genre_id
            group by g.genre_name, r.actor_id
            order by g.genre_name, cnt desc
           ) ga cross join
           (select @g := '', @rn := 0) params
      ) ga
where rn <= 3;

В 8.0+ используйте row_number() стандартный метод ANSI для этой функции.

Примечания:

  • Никогда не используйте запятые в предложении FROM. Всегда используйте правильный, явный синтаксис JOIN.
  • Используйте псевдонимы таблиц для обозначения сокращений столбцов, которые вы используете.
  • Укажите все имена столбцов в запросах, которые выиспользуются, особенно когда предложение FROM ссылается на несколько таблиц.
0 голосов
/ 26 мая 2018

Вы можете использовать ROW_NUMBER:

WITH cte AS (
  SELECT genre_name, actor_id, count(actor_id) AS cnt
    ,ROW_NUMBER() OVER(PARTITION BY genre_name ORDER BY count(actor_id) DESC) rn
  FROM movie
  JOIN movie_has_genre ON movie_has_genre.movie_id=movie.movie_id
  JOIN role            ON role.movie_id=movie.movie_id
  JOIN genre           ON genre.genre_id=movie_has_genre.genre_id  
  group by genre_name, actor_id 
)
SELECT *
FROM cte
WHERE rn <=3;

Пожалуйста, не используйте устаревший синтаксис с запятыми.

Как это работает:

  • рассчитывать количество заимя_генератора и идентификатор_актора
  • получить 3 самых больших значения для имени_генерала
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...