英文:
MySQL: Counting results from multiple LEFT JOINS
问题
我有三个描述数据的表格,其中包含一些主要内容。每个主要内容下面可以有多个类别,每个类别可以有多个段落。
主要内容表:
main_id | main_name |
---|---|
1 | bla |
2 | blub |
类别表:
cat_id | main_id | category_name |
---|---|---|
4 | 1 | bla cat |
5 | 1 | blub cat |
6 | 2 | ble cat |
7 | 2 | blib cat |
段落表:
seg_id | cat_id | segment_name |
---|---|---|
10 | 4 | bla seg |
11 | 4 | blub seg |
12 | 5 | bli seg |
13 | 6 | blob seg |
我正在通过在主要内容表中添加一列来显示每个主要内容下的类别数量,以及属于该主要内容的所有类别中的段落总数。
main_id | main_name | n_cats | n_segs |
---|---|---|---|
1 | bla | 2 | 3 |
2 | blub | 2 | 1 |
我尝试使用以下SQL语句:
SELECT
m.main_id, m.main_name, count(c.cat_id) as n_cats, count(s.seg_id) as n_segs
FROM main
LEFT JOIN categories c ON c.main_id = m.main_id
LEFT JOIN segments s ON s.cat_id = c.cat_id
GROUP BY m.main_id
但是它返回的n_cats和n_segs的值相同,而不是所期望的不同值:
main_id | main_name | n_cats | n_segs |
---|---|---|---|
1 | bla | 2 | 2 |
2 | blub | 2 | 2 |
英文:
I have three tables that describe data where there are some main things. Each thing can have several categories below it, and each category can have multiple segments.
main
main_id | main_name |
---|---|
1 | bla |
2 | blub |
categories
cat_id | main_id | category_name |
---|---|---|
4 | 1 | bla cat |
5 | 1 | blub cat |
6 | 2 | ble cat |
7 | 2 | blib cat |
segments
seg_id | cat_id | segment_name |
---|---|---|
10 | 4 | bla seg |
11 | 4 | blub seg |
12 | 5 | bli seg |
13 | 6 | blob seg |
I'm augmenting the main table with a column that shows the number of categories below each main thing, as well as the total number of segments in all categories belonging to it.
main_id | main_name | n_cats | n_segs |
---|---|---|---|
1 | bla | 2 | 3 |
2 | blub | 2 | 1 |
I tried with the following SQL statement:
SELECT
m.main_id, m.main_name, count(c.cat_id) as n_cats, count(s.seg_id) as n_segs
FROM main
LEFT JOIN categories c ON c.main_id = m.main_id
LEFT JOIN segments s ON s.cat_id = c.cat_id
GROUP BY m.main_id
But it yields the same values for n_cats and n_segs, instead of different ones as desired:
main_id | main_name | n_cats | n_segs |
---|---|---|---|
1 | bla | 2 | 2 |
2 | blub | 2 | 2 |
答案1
得分: 2
我使用相同的数据集执行了你的SQL查询,结果如下:
SELECT
m.main_id, m.main_name, COUNT(c.cat_id) AS n_cats, COUNT(s.seg_id) AS n_segs
FROM main m
LEFT JOIN categories c ON c.main_id = m.main_id
LEFT JOIN segments s ON s.cat_id = c.cat_id
GROUP BY m.main_id
我得到了与你的结果相同的结果,唯一的区别是我使用了别名FROM main m
。
英文:
I executed you SQL with same data set,
SELECT
m.main_id, m.main_name, COUNT(c.cat_id) AS n_cats, COUNT(s.seg_id) AS n_segs
FROM main m
LEFT JOIN categories c ON c.main_id = m.main_id
LEFT JOIN segments s ON s.cat_id = c.cat_id
GROUP BY m.main_id
I am getting this result, the only difference is I use m as an alias FROM main m
答案2
得分: 1
看起来你需要使用 COUNT(DISTINCT col) 来编写这个 SELECT 子句。
SELECT m.main_id, m.main_name,
count(DISTINCT c.cat_id) as n_cats,
count(DISTINCT s.seg_id) as n_segs
这样可以解决 JOIN 操作引起的组合爆炸问题。
英文:
It looks like you need this SELECT clause using COUNT(DISTINCT col).
SELECT m.main_id, m.main_name,
count(DISTINCT c.cat_id) as n_cats,
count(DISTINCT s.seg_id) as n_segs
This will undo the combinatorial explosion caused by your JOINs.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论