我有groups_areas
,groups
,groups_members
,groups_logs
个表格。
我想列出某个区域中的所有群组,其中的描述等来自groups
以及来自groups_members
和groups_logs
的统计信息。这是我的:
SELECT name, description
FROM groups g
INNER JOIN groups_areas ga ON ga.groupid = g.id WHERE ga.area = ?;
SELECT (SELECT COUNT(*)
FROM groups_members gm
WHERE gm.groupid = ?) as members,
(SELECT COUNT(*) FROM groups_logs gl WHERE gl.groupid = ?) as logs;
我认为问题在于,我需要以某种方式将第一个查询中的每个组ID与第二组子查询的组ID相关联。为该区域中的每个组提供name, description, members, logs
的结果集。
表结构(简化):
基
id (int) | name (text) | description (text)
1 engineering building things
2 sociology study of people
3 mining digging up the earth
4 economics study of various economic processes
groups_areas
groupid (int) | area (int)
1 2
2 2
3 1
4 3
groups_members
groupid (int) | member (int)
1 1
1 2
2 3
4 3
3 2
3 1
groups_logs
groupid (int) | log (int)
1 1
2 4
3 2
3 3
4 5
成员
id (int) | name (text)
1 max
2 john
3 elf
预期输出将是如下行:
engineering | building things | 2 | 1
mining | digging up the earth | 2 | 2
...
答案 0 :(得分:2)
使用左连接和不同计数。
SELECT g.name, g.description,
COUNT(DISTINCT gm.member) AS members,
COUNT(DISTINCT gl.log) AS logs
FROM groups g
INNER JOIN groups_areas ga ON (ga.groupid = g.id)
LEFT JOIN groups_members gm ON (gm.groupid = g.id)
LEFT JOIN groups_logs gl ON (gl.groupid = g.id)
WHERE ga.area = ?
GROUP BY g.name, g.description
ORDER BY g.name, g.description;
或者没有一个小组。加入子查询。
在寻找一个区域时,这可能会更慢,但对于所有区域可能会更快。
SELECT g.name, g.description,
gm.total as members,
gl.total as logs
FROM groups g
INNER JOIN groups_areas ga ON (ga.groupid = g.id)
LEFT JOIN (
select groupid, count(distinct member) as total
from groups_members
group by groupid
) gm ON (gm.groupid = g.id)
LEFT JOIN (
select groupid, count(distinct log) as total
from groups_logs
group by groupid
) gl ON (gl.groupid = g.id)
WHERE ga.area = ?
ORDER BY g.name, g.description;
测试数据
create table groups (id int PRIMARY KEY, name text, description text);
insert into groups values (1,'engineering','building things');
insert into groups values (2,'sociology','study of people');
insert into groups values (3,'mining','digging up the earth');
insert into groups values (4,'economics','study of various economic processes');
create table groups_areas (id int AUTO_INCREMENT PRIMARY KEY, groupid int, area int);
insert into groups_areas (groupid, area) values (1,2);
insert into groups_areas (groupid, area) values (2,2);
insert into groups_areas (groupid, area) values (3,1);
insert into groups_areas (groupid, area) values (4,3);
create table groups_members (id int AUTO_INCREMENT PRIMARY KEY, groupid int, member int);
insert into groups_members (groupid, member) values (1,1);
insert into groups_members (groupid, member) values (1,2);
insert into groups_members (groupid, member) values (2,3);
insert into groups_members (groupid, member) values (4,3);
insert into groups_members (groupid, member) values (3,2);
insert into groups_members (groupid, member) values (3,1);
create table groups_logs (id int AUTO_INCREMENT PRIMARY KEY, groupid int, log int);
insert into groups_logs (groupid, log) values (1,1);
insert into groups_logs (groupid, log) values (2,4);
insert into groups_logs (groupid, log) values (3,2);
insert into groups_logs (groupid, log) values (3,3);
insert into groups_logs (groupid, log) values (4,5);