需要左连接吗? WHERE 条件的行为类似于 INNER JOIN

LEFT JOIN needed? WHERE conditions behave similarly to INNER JOIN

尝试根据与样本 table 不同的标准对计数进行简单划分,按电影评级分组。我正在使用 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 吗?

提前致谢。

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

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

请注意,我认为您当前执行 self-join 的方法方向错误。相反,我们可以只扫描整个 table 并计算每个 rating 组的各种标题。

您不需要任何加入。

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

Group by 1 / order by 1 表示 select

中的第一列

count 不会计算任何空值