我有下表电影:
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;
问题是我想将上面的两个查询合并到一个查询中,以便可以看到上面的输出表。我不确定该怎么做。任何见解都会受到赞赏。
答案 0 :(得分:2)
您可以尝试使用UNION ALL
组合Genres
和keyword
表并添加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 |
答案 1 :(得分:0)
下面的查询首先获取所有电影,以及与正在寻找的电影具有相同流派的电影的内在联系。这样一来,您就可以摆脱任何电影,而无需与要搜索的电影有任何共同点。
在这种情况下,我正在使用您查询的类型频率作为派生表。我还删除了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