Mysql 按最大常用类型的顺序获取电影,然后是关键字

Mysql 按最大常用类型的顺序获取电影,然后是关键字,mysql,sql,Mysql,Sql,我有以下表格: id | title | year 315 Harry Potter and the Deathly Hallows: Part 2 2011 407 Cinderella 2015 826 The Shape of Water

我有以下表格:

id    |                  title                           |    year 
315      Harry Potter and the Deathly Hallows: Part 2         2011
407      Cinderella                                           2015
826      The Shape of Water                                   2017
799      Enchanted                                            2007
523      How to Train Your Dragon                             2010
618      Crazy Rich Asians                                    2018
以及表格类型:

movie_id   |    genre
315             adventure
315             fantasy
315             mystery
315             drama
407             drama
407             fantasy
826             drama
826             thriller
826             adventure
826             horror
799             fantasy
799             comedy
799             romance
523             drama
523             fantasy
618             romance
618             comedy
和表关键字:

movie_id     |       keyword 
315                  magic
315                  wizards
315                  witch
315                  friendship
315                  abuse 
407                  prince 
407                  fairy tale
407                  magic
407                  poor girl
407                  abuse 
826                  scientist
826                  mute
826                  friendship
799                  musical
799                  magic
799                  witch
799                  friendship
523                  viking
523                  boy
523                  fire
618                  singapore
618                  wedding
618                  money
我正在尝试构造一个查询,该查询将输出与给定电影具有相同类型的所有电影。如果有相同数量的普通类型的电影,那么我想按照最大常用关键字的顺序对这些电影进行排名

例如,如果电影是《哈利波特与死亡圣器:第2部分》,那么查询的输出将是:

title                      |      genre_frequency     |    keyword_frequency
Cinderella                        2                        2
The Shape of Water                2                        1
How to Train Your Dragon          2                        0
Enchanted                         1                        3
输出中不包括没有与指定电影相同的任何类型的电影,例如疯狂富有的亚洲人

我有两个查询,可以给我的体裁_频率和关键字_频率

select m.*, genre_frequency from movie m
join (
     select m.id, count(*) as genre_frequency
     from movie m
     join genre g on m.id=g.movie_id
     where g.genre in (select g1.genre 
                       from genre g1
                       where g1.movie_id=315)
     group by m.id
     ) f
 on m.id=f.id
 where m <> 315
 order by f.genre_frequency desc;


select m.*, keyword_frequency from movie m
join (
     select m.id, count(*) as keyword_frequency
     from movie m
     join keyword k on m.id=k.movie_id
     where k.keyword in (select k1.keyword
                       from keyword k1
                       where k1.movie_id=315)
     group by m.id
     ) f
 on m.id=f.id
 where m <> 315
 order by f.keyword_frequency desc;
问题是,我想将上面的两个查询合并成一个查询,这样我就可以像上面看到的那样查看输出表。我不知道我怎样才能做到这一点。您可以尝试使用UNION ALL组合体裁和关键字表,并添加grp列以将结果集分成两部分。然后使用条件聚合函数

问题1


下面的查询首先获取所有电影,并将其与您正在寻找的电影具有相同类型的电影进行内部连接。这将允许删除与要搜索的电影没有任何共同类型的任何电影

在本例中,我使用您对流派频率的查询作为派生表。我还删除了where语句中的IN子句,并使用了另一个内部联接以获得更好的性能

第二个派生表,即使用LEFT JOIN连接的表,是用于获取关键字频率的查询。相同的逻辑适用于类型频率表,唯一的区别是左连接,因为两部电影可以有相同的类型,但没有关键字

请注意select子句中的IFNULL语句,如果没有找到常用关键字,则返回0

最后,我们只是先按体裁频率排序,然后按关键字频率降序排序

select m.title, IFNULL(g_fq.genre_frequency,0), 
IFNULL(k_fq.keyword_frequency,0)
FROM movie m
INNER JOIN 
(select m.id as movie_id, genre_frequency from movie m
join (
     select m.id, count(*) as genre_frequency
     from movie m
     join genre g on m.id=g.movie_id
     INNER JOIN 
       (select g1.genre 
       from genre g1
       where g1.movie_id=315) as a on a.genre=g.genre
     group by m.id
     ) f
 on m.id=f.id
 where m.id <> 315
 ) as g_fq ON m.id=g_fq.movie_id

 LEFT JOIN 
 (
select m.id as movie_id, keyword_frequency from movie m
join (
     select m.id, count(*) as keyword_frequency
     from movie m
     join keyword k on m.id=k.movie_id
     INNER JOIN
      (select k1.keyword
       from keyword k1
       where k1.movie_id=315) as b on b.keyword=k.keyword
     group by m.id
     ) f
 on m.id=f.id
 where m.id <> 315
 ) as k_fq on m.id=k_fq.movie_id
 order by IFNULL(g_fq.genre_frequency,0) DESC,IFNULL(k_fq.keyword_frequency,0) DESC



当t1.grp='g'时,行'countCASE'然后1作为类型\频率结束,当t1.grp='k'时,行'countCASE'然后1作为关键字\频率结束,这是条件聚合函数。当我不确定条件聚合函数中t1.grp='g'和t1.grp='k'的含义时,使用Case计数。@D-Shih。真正不需要的地方。您可以使用“流派\频率>0”或“关键字\频率>0”来代替。我使用相同的表尝试了上述查询,但是得到了一个错误列t1.name不存在,第12行:其中t1.name位于select g1.GREER中。我认为这是因为联接产生的表t1没有名为“name”的属性。有没有办法让上面的代码正常工作?任何见解都将不胜感激。
select m.title, IFNULL(g_fq.genre_frequency,0), 
IFNULL(k_fq.keyword_frequency,0)
FROM movie m
INNER JOIN 
(select m.id as movie_id, genre_frequency from movie m
join (
     select m.id, count(*) as genre_frequency
     from movie m
     join genre g on m.id=g.movie_id
     INNER JOIN 
       (select g1.genre 
       from genre g1
       where g1.movie_id=315) as a on a.genre=g.genre
     group by m.id
     ) f
 on m.id=f.id
 where m.id <> 315
 ) as g_fq ON m.id=g_fq.movie_id

 LEFT JOIN 
 (
select m.id as movie_id, keyword_frequency from movie m
join (
     select m.id, count(*) as keyword_frequency
     from movie m
     join keyword k on m.id=k.movie_id
     INNER JOIN
      (select k1.keyword
       from keyword k1
       where k1.movie_id=315) as b on b.keyword=k.keyword
     group by m.id
     ) f
 on m.id=f.id
 where m.id <> 315
 ) as k_fq on m.id=k_fq.movie_id
 order by IFNULL(g_fq.genre_frequency,0) DESC,IFNULL(k_fq.keyword_frequency,0) DESC