需要左连接吗? 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 不会计算任何空值
尝试根据与样本 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 不会计算任何空值