假设多对多关系如何计算每组用户数?

时间:2017-06-03 13:19:40

标签: mysql sql select count

我有两个表usersgroups,以及定义多对多关系users_groups的第三个表:

表"组":

CREATE TABLE `group` (
  `ID` int(11) NOT NULL,
  `creation_date` date NOT NULL,
  `type` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `group` (`ID`, `creation_date`, `type`) VALUES
(1, '2017-06-01', 'AAA'),
(2, '2017-06-01', 'BBB'),
(3, '2017-06-01', 'CCC');

表"用户":

CREATE TABLE `user` (
  `ID` int(11) NOT NULL,
  `name` varchar(50) NOT NULL,
  `surnames` varchar(100) NOT NULL,
  `birthdate` date NOT NULL,
  `qualification` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `user` (`ID`, `name`, `surnames`, `birthdate`, `qualification`) VALUES
(1, 'xxx', 'xxx', '1989-03-03', 'A'),
(2, 'xxx', 'xxx', '1990-06-15', 'A'),
(3, 'xxx', 'xxx', '1982-06-14', 'B'),
(4, 'xxx', 'xxx', '1988-06-19', 'B'),
(5, 'xxx', 'xxx', '1984-03-12', 'B'),
(6, 'xxx', 'xxx', '1987-12-19', 'C');

表" users_groups":

CREATE TABLE `user_group` (
  `ID` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `group_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `user_group` (`ID`, `user_id`, `group_id`) VALUES
(1, 1, 1),
(2, 2, 1),
(3, 3, 2),
(4, 4, 2),
(5, 5, 2),
(6, 6, 3);

我需要计算每组的用户数量并总结结果如下:

ID   creation_date    type   users_count_per_group
1    2017-06-01       AAA    2
2    2017-06-01       BBB    3
3    2017-06-01       CCC    1

这是我当前的查询。我遇到了多对多关系,这意味着同一个用户可能会出现在不同的组中(尽管在我的示例数据中,所有用户每个组只出现一次):

SELECT `group`.`ID`, `group`.`creation_date`, `group`.`type`, COUNT(*) 
FROM `group`, `user`, `user_group` 
WHERE `group`.`ID`=`user_group`.`group_id` 
      AND `user`.`ID`=`user_group`.`user_id`; 

3 个答案:

答案 0 :(得分:2)

您错过了group by条款:

SELECT   `group`.`ID`, `group`.`creation_date`, `group`.`type`, COUNT(*)  
FROM     `group`, `user`, `user_group`
WHERE    `group`.`ID`=`user_group`.`group_id` AND 
         `user`.`ID`=`user_group`.`user_id`
GROUP BY `group`.`ID`, `group`.`creation_date`, `group`.`type`

请注意,隐式连接(即,在from子句中使用多个表)已被认为已弃用很长一段时间了。最好使用明确的join子句:

SELECT   `group`.`ID`, `group`.`creation_date`, `group`.`type`, COUNT(*)  
FROM     `group`
JOIN     `user_group` ON `group`.`ID` = `user_group`.`group_id`
JOIN     `user` ON `user`.`ID` = `user_group`.`user_id`
GROUP BY `group`.`ID`, `group`.`creation_date`, `group`.`type`

答案 1 :(得分:1)

试试这个:

SELECT `group`.`ID`, `group`.`creation_date`, `group`.`type`, COUNT(*) 
FROM `user_group`
JOIN `user` on `user`.ID = `user_group`.`user_id`  
JOIN `group` on `group`.ID = `user_group`.`group_id`
GROUP BY `user_group`.`group_id`

答案 2 :(得分:1)

您无需加入users表即可执行所需操作。因此,查询只需要一个连接:

SELECT g.id, g.creation_date, g.type, COUNT(*) as users_count_per_group
FROM `group` g JOIN
     user_group ug
     ON g.id = ug.group_id
GROUP BY g.id, g.creation_date, g.type;

补充说明:

  • group是一个非常糟糕的表名,因为它是一个SQL关键字。我将表格命名为复数形式,这通常可以避免这个问题。
  • 表别名使查询更易于编写和阅读。
  • 反引号使查询更难写和阅读。