MySQL 来自 FROM 的相关子查询
MySQL correlated subquery at FROM
我正在与 Sakila sample database 合作,并试图获得每个国家/地区观看次数最多的电影。到目前为止,我已经通过以下查询获得了某个国家/地区观看次数最多的电影:
SELECT
F.title, CO.country, count(F.film_id) as times
FROM
customer C
INNER JOIN
address A ON C.address_id = A.address_id
INNER JOIN
city CI ON A.city_id = CI.city_id
INNER JOIN
country CO ON CI.country_id = CO.country_id
INNER JOIN
rental R ON C.customer_id = R.customer_id
INNER JOIN
inventory I ON R.inventory_id = I.inventory_id
INNER JOIN
film F ON I.film_id = F.film_id
WHERE
CO.country_id = 1
GROUP BY
F.film_id
ORDER BY
times DESC
LIMIT 1;
我想我将不得不在另一个查询的 FORM 中使用这个查询或类似的东西,但我已经尝试了所有我能想到的,但我完全无法弄清楚如何去做。
提前致谢!
我承认,这是一个非常难的查询。不过好吧,只要它有效。
解释:
- 子查询:与您已有的几乎相同。没有
WHERE
和 LIMIT
。每个国家 的 movie-count 列表
- 结果,按国家/地区分组
GROUP_CONCAT(title ORDER BY times DESC SEPARATOR '|||')
,将给出 'row' 中的所有标题,第一个是 most-viewed 标题。分隔符无关紧要,只要您确定它永远不会出现在标题中即可。
SUBSTRING_INDEX('...', '|||', 1)
导致字符串的第一部分,直到它找到 |||
,在本例中是第一个(因此 most-viewed)标题
完整查询:
SELECT
country_name,
SUBSTRING_INDEX(
GROUP_CONCAT(title ORDER BY times DESC SEPARATOR '|||'),
'|||', 1
) as title,
MAX(times)
FROM (
SELECT
F.title AS title,
CO.country_id AS country_id,
CO.country AS country_name,
count(F.film_id) as times
FROM customer C INNER JOIN address A ON C.address_id = A.address_id
INNER JOIN city CI ON A.city_id = CI.city_id
INNER JOIN country CO ON CI.country_id = CO.country_id
INNER JOIN rental R ON C.customer_id = R.customer_id
INNER JOIN inventory I ON R.inventory_id = I.inventory_id
INNER JOIN film F ON I.film_id = F.film_id
GROUP BY F.film_id, CO.country_id
) AS count_per_movie_per_country
GROUP BY country_id
概念验证(只要子查询正确):SQLFiddle
我正在与 Sakila sample database 合作,并试图获得每个国家/地区观看次数最多的电影。到目前为止,我已经通过以下查询获得了某个国家/地区观看次数最多的电影:
SELECT
F.title, CO.country, count(F.film_id) as times
FROM
customer C
INNER JOIN
address A ON C.address_id = A.address_id
INNER JOIN
city CI ON A.city_id = CI.city_id
INNER JOIN
country CO ON CI.country_id = CO.country_id
INNER JOIN
rental R ON C.customer_id = R.customer_id
INNER JOIN
inventory I ON R.inventory_id = I.inventory_id
INNER JOIN
film F ON I.film_id = F.film_id
WHERE
CO.country_id = 1
GROUP BY
F.film_id
ORDER BY
times DESC
LIMIT 1;
我想我将不得不在另一个查询的 FORM 中使用这个查询或类似的东西,但我已经尝试了所有我能想到的,但我完全无法弄清楚如何去做。
提前致谢!
我承认,这是一个非常难的查询。不过好吧,只要它有效。
解释:
- 子查询:与您已有的几乎相同。没有
WHERE
和LIMIT
。每个国家 的 movie-count 列表
- 结果,按国家/地区分组
GROUP_CONCAT(title ORDER BY times DESC SEPARATOR '|||')
,将给出 'row' 中的所有标题,第一个是 most-viewed 标题。分隔符无关紧要,只要您确定它永远不会出现在标题中即可。SUBSTRING_INDEX('...', '|||', 1)
导致字符串的第一部分,直到它找到|||
,在本例中是第一个(因此 most-viewed)标题
完整查询:
SELECT
country_name,
SUBSTRING_INDEX(
GROUP_CONCAT(title ORDER BY times DESC SEPARATOR '|||'),
'|||', 1
) as title,
MAX(times)
FROM (
SELECT
F.title AS title,
CO.country_id AS country_id,
CO.country AS country_name,
count(F.film_id) as times
FROM customer C INNER JOIN address A ON C.address_id = A.address_id
INNER JOIN city CI ON A.city_id = CI.city_id
INNER JOIN country CO ON CI.country_id = CO.country_id
INNER JOIN rental R ON C.customer_id = R.customer_id
INNER JOIN inventory I ON R.inventory_id = I.inventory_id
INNER JOIN film F ON I.film_id = F.film_id
GROUP BY F.film_id, CO.country_id
) AS count_per_movie_per_country
GROUP BY country_id
概念验证(只要子查询正确):SQLFiddle