MYSQL:加入1:N课程类别的有条件课程注册计数?
我花了太长时间思考这个问题的题目,所以我希望我选择的题目是可以理解的。但让我解释一下:MYSQL:加入1:N课程类别的有条件课程注册计数?,mysql,sql,group-by,count,subquery,Mysql,Sql,Group By,Count,Subquery,我花了太长时间思考这个问题的题目,所以我希望我选择的题目是可以理解的。但让我解释一下: CREATE TABLE IF NOT EXISTS `course` ( `course_id` int(11) NOT NULL, `course_name` varchar(255) NOT NULL ) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; INSERT INTO `course` (`course_id`, `cours
CREATE TABLE IF NOT EXISTS `course` (
`course_id` int(11) NOT NULL,
`course_name` varchar(255) NOT NULL
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
INSERT INTO `course` (`course_id`, `course_name`) VALUES
(1, 'Course A'),
(2, 'Course B'),
(3, 'Course C'),
(4, 'Course D'),
(5, 'Course E');
CREATE TABLE IF NOT EXISTS `course_category` (
`course_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
INSERT INTO `course_category` (`course_id`, `category_id`) VALUES
(1, 1),
(1, 2),
(1, 3),
(2, 2),
(3, 1),
(3, 3),
(5, 1),
(5, 3);
CREATE TABLE IF NOT EXISTS `enrolment` (
`enrolment_id` int(11) NOT NULL,
`course_id` int(11) NOT NULL,
`status` int(11) NOT NULL
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
INSERT INTO `enrolment` (`enrolment_id`, `course_id`, `status`) VALUES
(1, 1, 0),
(2, 1, 1),
(3, 1, 0),
(4, 3, 0),
(5, 3, 0),
(6, 3, 0),
(7, 4, 1),
(8, 4, 1),
(9, 4, 1),
(10, 4, 0);
ALTER TABLE `course`
ADD PRIMARY KEY (`course_id`);
ALTER TABLE `enrolment`
ADD PRIMARY KEY (`enrolment_id`);
ALTER TABLE `course`
MODIFY `course_id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=9;
ALTER TABLE `enrolment`
MODIFY `enrolment_id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=11;
小提琴:
(还有一个category
表,但这对问题并不重要。)
我试图得到以下结果:
SELECT
course_name,
GROUP_CONCAT(DISTINCT category_id) AS category_ids,
COUNT(DISTINCT enrolment_id) as enrolments
FROM
course
LEFT JOIN course_category USING (course_id)
LEFT JOIN enrolment USING (course_id)
WHERE status = 1 OR status IS NULL
GROUP BY course_id
+-------------+--------------+------------+
| course_name | category_ids | enrolments |
+-------------+--------------+------------+
| Course A | 3,1,2 | 1 |
| Course D | NULL | 3 |
+-------------+--------------+------------+
SELECT
course_name,
GROUP_CONCAT(DISTINCT category_id) AS category_ids,
SUM(IF(status=1,1,0)) as enrolments
FROM
course
LEFT JOIN course_category USING (course_id)
LEFT JOIN enrolment USING (course_id)
GROUP BY course_id
+-------------+--------------+------------+
| course_name | category_ids | enrolments |
+-------------+--------------+------------+
| Course A | 3,1,2 | 3 |
| Course B | 2 | 0 |
| Course C | 1,3 | 0 |
| Course D | NULL | 3 |
| Course E | 1,3 | 0 |
+-------------+--------------+------------+
SUM
,以及带有DISTINCT
关键字和WHERE
条件的COUNT
,但我无法满足所有必要的要求
尝试计数
:
SELECT
course_name,
GROUP_CONCAT(DISTINCT category_id) AS category_ids,
COUNT(DISTINCT enrolment_id) as enrolments
FROM
course
LEFT JOIN course_category USING (course_id)
LEFT JOIN enrolment USING (course_id)
WHERE status = 1 OR status IS NULL
GROUP BY course_id
+-------------+--------------+------------+
| course_name | category_ids | enrolments |
+-------------+--------------+------------+
| Course A | 3,1,2 | 1 |
| Course D | NULL | 3 |
+-------------+--------------+------------+
SELECT
course_name,
GROUP_CONCAT(DISTINCT category_id) AS category_ids,
SUM(IF(status=1,1,0)) as enrolments
FROM
course
LEFT JOIN course_category USING (course_id)
LEFT JOIN enrolment USING (course_id)
GROUP BY course_id
+-------------+--------------+------------+
| course_name | category_ids | enrolments |
+-------------+--------------+------------+
| Course A | 3,1,2 | 3 |
| Course B | 2 | 0 |
| Course C | 1,3 | 0 |
| Course D | NULL | 3 |
| Course E | 1,3 | 0 |
+-------------+--------------+------------+
在这种情况下,只有当至少有一个状态为1的注册或该课程没有注册时,我才能获得该课程,否则结果中会丢失整个课程
尝试求和
:
SELECT
course_name,
GROUP_CONCAT(DISTINCT category_id) AS category_ids,
COUNT(DISTINCT enrolment_id) as enrolments
FROM
course
LEFT JOIN course_category USING (course_id)
LEFT JOIN enrolment USING (course_id)
WHERE status = 1 OR status IS NULL
GROUP BY course_id
+-------------+--------------+------------+
| course_name | category_ids | enrolments |
+-------------+--------------+------------+
| Course A | 3,1,2 | 1 |
| Course D | NULL | 3 |
+-------------+--------------+------------+
SELECT
course_name,
GROUP_CONCAT(DISTINCT category_id) AS category_ids,
SUM(IF(status=1,1,0)) as enrolments
FROM
course
LEFT JOIN course_category USING (course_id)
LEFT JOIN enrolment USING (course_id)
GROUP BY course_id
+-------------+--------------+------------+
| course_name | category_ids | enrolments |
+-------------+--------------+------------+
| Course A | 3,1,2 | 3 |
| Course B | 2 | 0 |
| Course C | 1,3 | 0 |
| Course D | NULL | 3 |
| Course E | 1,3 | 0 |
+-------------+--------------+------------+
在这种情况下,所有的课程都有,但计算是错误的,因为我无法计算不同的入学人数
我错过了哪一个机会
SELECT c.course_name,
GROUP_CONCAT(cc.category_id ORDER BY cc.category_id) category_ids,
COALESCE(e.status, 0) enrolments
FROM course c
LEFT JOIN course_category cc USING (course_id)
-- calculate statuses per course separately
LEFT JOIN (SELECT course_id, SUM(status) status -- maybe SUM(status=1)?
FROM enrolment
GROUP BY course_id ) e USING (course_id)
GROUP BY c.course_name, e.status
我认为用相关子查询而不是外部聚合来表达会更简单:
select c.course_name,
(
select group_concat(cc.category_id order by cc.category_id)
from course_category cc
where cc.course_id = c.course_id
) category_ids,
(
select coalesce(sum(e.status), 0)
from enrolment e
where e.course_id = c.course_id
) enrolments
from course c
order by c.course_name
请提供作为创建表+插入(或在线小提琴)的源数据。谢谢提醒,添加了小提琴。请记住,我更愿意保持我的精神上的衣服,谢谢。考虑在应用中处理数据显示的问题。code@Strawberry谢谢你的笑声!也支持这项建议。我很想相应地更改应用程序代码,但遗憾的是,这不在我的控制范围之内。它希望已经以某种方式准备好结果。