LEFT JOIN需要吗?条件的行为与INNER JOIN类似

时间:2017-02-09 05:35:50

标签: mysql left-join self-join

尝试根据样本表中的不同标准对计数进行简单划分,按电影评级进行分组。我正在使用MySQL默认提供的示例SAKILA架构。

您可以看到我希望从前两个查询中看到的单独计数:

首先查询:

SELECT f1.rating, count(f1.title)
FROM sakila.film f1
WHERE f1.title like '%BA%'
GROUP BY rating
ORDER BY rating ASC

第一个查询结果:

    rating  count(f1.title)
    G       4
    PG      5
    PG-13   8
    R       6
    NC-17   6

第二次查询:

SELECT f1.rating, count(f1.title)
FROM sakila.film f1
WHERE f1.title like '%AM%'
GROUP BY rating
ORDER BY rating ASC

第二个查询结果:

    rating  count(f1.title)
    G       8
    PG      6
    PG-13   9
    R       18
    NC-17   7

我所追求的是G等级划分为4/8,PG等级划分为5/6,等等。

我原本希望以下查询可以完成此计算,但是对我来说LEFT JOIN似乎充当了INNER JOIN,因为这两个WHERE条件只会导致1个包含'BA'和'AM'的电影,这就是结果的原因:

问题查询:

SELECT f1.rating, count(f1.title)/count(f2.title) 
FROM sakila.film f1
LEFT JOIN sakila.film f2
ON f1.film_id = f2.film_id
WHERE f1.title like '%BA%'
AND f2.title like '%AM%'
GROUP BY rating
ORDER BY rating ASC

问题查询结果:

    rating  count(f1.title)/count(f2.title) 
    PG-13   1.0000

如何修改有问题的查询以按预期划分前两个查询的计数并按评级划分?我是否需要使用UNION ALL重写查询,或者在这种情况下仍然可以使用LEFT JOIN?

提前致谢。

2 个答案:

答案 0 :(得分:3)

您可以在此处使用条件聚合:

SELECT rating,
       SUM(CASE WHEN title LIKE '%BA%' THEN 1 ELSE 0 END) /
       SUM(CASE WHEN title LIKE '%AM%' THEN 1 ELSE 0 END) AS the_ratio
FROM sakila.film
GROUP BY rating
ORDER BY rating ASC

请注意,我认为您目前进行自我加入的方法是错误的。相反,我们只需对整个表格进行一次扫描,并计算每个rating组的各种标题。

答案 1 :(得分:1)

您不需要任何加入。

SELECT 
  rating,
  count(if (title like '%BA%', 1, null)) / count(if (title like '%AM%', 1, null))
FROM sakila.film
GROUP BY 1
ORDER BY 1

分组1 /分1表示选择

中的第一列

count不会依赖任何空值