Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MYSQL:加入1:N课程类别的有条件课程注册计数?_Mysql_Sql_Group By_Count_Subquery - Fatal编程技术网

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 |
+-------------+--------------+------------+
  • 所有课程都必须在结果集中
  • 每个课程的类别ID必须是单个字符串,用逗号分隔
  • 每门课程应计算状态为1的注册总数(请记住,“1”在这里只是一个示例,也可以是另一个数字或要检查的字符串)
  • 我曾尝试使用带有条件的
    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谢谢你的笑声!也支持这项建议。我很想相应地更改应用程序代码,但遗憾的是,这不在我的控制范围之内。它希望已经以某种方式准备好结果。