【问题标题】:Get movies in order of maximum common genres, then keywords按最常见类型的顺序获取电影,然后是关键字
【发布时间】:2019-04-14 07:37:34
【问题描述】:

我有下表电影:

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

和 table 关键字:

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

与指定电影没有任何共同类型的电影不包含在输出中(例如 Crazy Rich Asians)。

我有两个查询可以给我genre_frequency 和keyword_frequency。

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;

问题是我想将上面的两个查询组合成一个查询,这样我就可以得到如上所示的输出表。我不确定我该怎么做。任何见解都值得赞赏。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    您可以尝试使用UNION ALL 组合Genreskeyword 表并添加grp 列以将结果集拆分为两部分。然后使用条件聚合函数。

    查询 #1

    select m.title, 
          count(CASE WHEN t1.grp = 'g' THEN 1 END) as genre_frequency,
          count(CASE WHEN t1.grp = 'k' THEN 1 END) as keyword_frequency
    from Movies m
    join (
        SELECT movie_id,genre name,'g' grp
        FROM Genres 
        UNION ALL
        SELECT movie_id,keyword,'k' grp
        FROM keyword
    ) t1 on m.id=t1.movie_id
    where (t1.name in (select g1.genre 
                   from Genres g1
                   where g1.movie_id=315) or 
          t1.name in (select k1.keyword 
                   from keyword k1
                   where k1.movie_id=315)) 
    AND m.id <> 315
    group by m.title;
    
    | title                    | genre_frequency | keyword_frequency |
    | ------------------------ | --------------- | ----------------- |
    | Cinderella               | 2               | 2                 |
    | Enchanted                | 1               | 3                 |
    | How to Train Your Dragon | 2               | 0                 |
    | The Shape of Water       | 2               | 1                 |
    

    View on DB Fiddle

    【讨论】:

    • 行'count(CASE WHEN t1.grp = 'g' THEN 1 END)作为genre_frequency,count(CASE WHEN t1.grp = 'k' THEN 1 END)作为keyword_frequency'做什么?
    • 这是条件聚合函数。 CountCase when
    • 我不确定 t1.grp = 'g' 和 t1.grp = 'k' 在条件聚合函数中是什么意思。
    • @D-Shih 。 . . where 并不是真正需要的。你可以改用having genre_frequency &gt; 0 or keyword_frequency &gt; 0
    • 我用相同的表尝试了上述查询,但是我得到一个错误“列 t1.name 不存在,第 12 行:where (t1.name in (select g1.genre". I认为这是因为连接产生的表 t1 没有名为“名称”的属性。有什么方法可以让上面的代码工作吗?任何见解都值得赞赏。
    【解决方案2】:

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

    在这种情况下,我将您对流派频率的查询用作派生表。我还删除了 where 语句中的 IN 子句,并使用了另一个内连接以获得更好的性能。

    第二个派生表,使用 LEFT JOIN 连接的表是您用来获取关键字频率的查询。与流派频率表相同的逻辑,唯一的区别是 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
    
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-07
      • 2012-09-02
      • 2021-09-03
      • 2016-07-17
      相关资源
      最近更新 更多