MySQL 50 题。

MySQL 50 题。


文章目录


数据库。

sql 复制代码
CREATE SCHEMA `new_schema` DEFAULT CHARACTER SET utf8mb4 ;


Operation failed: There was an error while applying the SQL script to the database.
Executing:
CREATE SCHEMA `new_schema` DEFAULT CHARACTER SET utf8mb4 ;

ERROR 1044: Access denied for user 'lyfgeek'@'%' to database 'new_schema'
SQL Statement:
CREATE SCHEMA `new_schema` DEFAULT CHARACTER SET utf8mb4
sql 复制代码
CREATE SCHEMA `mysql_fifty` DEFAULT CHARACTER SET utf8 ;
sql 复制代码
CREATE TABLE `lyfgeek`.`student`
(
    `id`             BIGINT      NOT NULL AUTO_INCREMENT COMMENT '主键 id。',
    `s_id`           VARCHAR(45) NOT NULL DEFAULT '' COMMENT '学生 id。',
    `s_name`         VARCHAR(45) NOT NULL DEFAULT '' COMMENT '姓名。',
    `s_birth`        VARCHAR(45) NOT NULL DEFAULT '' COMMENT '出生年月。',
    `s_sex`          VARCHAR(45) NOT NULL DEFAULT '' COMMENT '性别。',
    `db_insert_time` TIMESTAMP   NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'db_insert_time。',
    `db_update_time` TIMESTAMP   NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'db_update_time。',
    `db_deleted`     INT         NOT NULL DEFAULT 0 COMMENT 'db_deleted。',
    PRIMARY KEY (`id`, `s_id`),
    UNIQUE INDEX `s_id_UNIQUE` (`s_id` ASC) VISIBLE
)
    ENGINE = InnoDB
    DEFAULT CHARACTER SET = utf8mb4
    COMMENT = '学生。';


-- 课程表。
CREATE TABLE `lyfgeek`.`course`
(
    `id`             BIGINT      NOT NULL AUTO_INCREMENT COMMENT '主键 id。',
    `c_id`           VARCHAR(45) NOT NULL DEFAULT '' COMMENT '课程 id。',
    `c_name`         VARCHAR(45) NOT NULL DEFAULT '' COMMENT '课程名称。',
    `t_id`           VARCHAR(45) NOT NULL DEFAULT '' COMMENT '教师 id。',
    `db_insert_time` TIMESTAMP   NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'db_insert_time。',
    `db_update_time` TIMESTAMP   NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'db_update_time。',
    `db_deleted`     INT         NOT NULL DEFAULT 0 COMMENT 'db_deleted。',
    PRIMARY KEY (`id`),
    UNIQUE INDEX `c_id_UNIQUE` (`c_id` ASC) VISIBLE
)
    ENGINE = InnoDB
    DEFAULT CHARACTER SET = utf8mb4
    COMMENT = '成绩。';


-- 教师表。
CREATE TABLE `lyfgeek`.`teacher`
(
    `id`             BIGINT      NOT NULL AUTO_INCREMENT COMMENT '主键 id。',
    `t_id`           VARCHAR(45) NOT NULL DEFAULT '' COMMENT '教师 id。',
    `t_name`         VARCHAR(45) NOT NULL DEFAULT '' COMMENT '姓名。',
    `db_insert_time` TIMESTAMP   NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'db_insert_time。',
    `db_update_time` TIMESTAMP   NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'db_update_time。',
    `db_deleted`     INT         NOT NULL DEFAULT 0 COMMENT 'db_deleted。',
    PRIMARY KEY (`id`, `t_id`),
    UNIQUE INDEX `t_id_UNIQUE` (`t_id` ASC) VISIBLE
)
    ENGINE = InnoDB
    DEFAULT CHARACTER SET = utf8mb4
    COMMENT = '教师。';


-- 成绩表。
CREATE TABLE `lyfgeek`.`score`
(
    `id`             BIGINT      NOT NULL AUTO_INCREMENT COMMENT '主键 id。',
    `s_id`           VARCHAR(45) NOT NULL DEFAULT '' COMMENT '学生 id。',
    `c_id`           VARCHAR(45) NOT NULL DEFAULT '' COMMENT '课程 id。',
    `s_score`        INT         NULL     DEFAULT NULL COMMENT '成绩。',
    `db_insert_time` TIMESTAMP   NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'db_insert_time。',
    `db_update_time` TIMESTAMP   NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'db_update_time。',
    `db_deleted`     INT         NOT NULL DEFAULT 0 COMMENT 'db_deleted。',
    PRIMARY KEY (`id`)
)
    ENGINE = InnoDB
    DEFAULT CHARACTER SET = utf8mb4
    COMMENT = '成绩。';


# 学生表测试数据。
INSERT INTO `lyfgeek`.`student` (`s_id`, `s_name`, `s_birth`, `s_sex`)
VALUES ('01', '学生 1', '2021-01-01', '男');
INSERT INTO `lyfgeek`.`student` (`s_id`, `s_name`, `s_birth`, `s_sex`)
VALUES ('02', '学生 2', '2022-02-02', '男');
INSERT INTO `lyfgeek`.`student` (`s_id`, `s_name`, `s_birth`, `s_sex`)
VALUES ('03', '学生 3', '2023-03-03', '男');
INSERT INTO `lyfgeek`.`student` (`s_id`, `s_name`, `s_birth`, `s_sex`)
VALUES ('04', '学生 4', '2024-04-04', '男');
INSERT INTO `lyfgeek`.`student` (`s_id`, `s_name`, `s_birth`, `s_sex`)
VALUES ('05', '学生 5', '2025-05-05', '女');
INSERT INTO `lyfgeek`.`student` (`s_id`, `s_name`, `s_birth`, `s_sex`)
VALUES ('06', '学生 6', '2026-06-06', '女');
INSERT INTO `lyfgeek`.`student` (`s_id`, `s_name`, `s_birth`, `s_sex`)
VALUES ('07', '学生 7', '2027-07-07', '女');
INSERT INTO `lyfgeek`.`student` (`s_id`, `s_name`, `s_birth`, `s_sex`)
VALUES ('08', '学生 8', '2028-08-08', '女');


# 课程表测试数据。
INSERT INTO `lyfgeek`.`course`(`c_id`, `c_name`, `t_id`)
VALUES ('01', '语文', '02');
INSERT INTO `lyfgeek`.`course`(`c_id`, `c_name`, `t_id`)
VALUES ('02', '数学', '01');
INSERT INTO `lyfgeek`.`course`(`c_id`, `c_name`, `t_id`)
VALUES ('03', '英语', '03');


# 教师表测试数据。
INSERT INTO `lyfgeek`.`teacher` (`t_id`, `t_name`)
VALUES ('01', '老师 1');
INSERT INTO `lyfgeek`.`teacher` (`t_id`, `t_name`)
VALUES ('02', '老师 2');
INSERT INTO `lyfgeek`.`teacher` (`t_id`, `t_name`)
VALUES ('03', '老师 3');


# 成绩表测试数据。
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('01', '01', '80');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('01', '02', '90');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('01', '03', '99');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('02', '01', '70');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('02', '02', '60');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('02', '03', '80');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('03', '01', '80');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('03', '02', '80');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('03', '03', '80');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('04', '01', '50');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('04', '02', '30');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('04', '03', '20');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('05', '01', '76');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('05', '02', '87');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('06', '01', '31');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('06', '03', '34');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('07', '02', '89');
INSERT INTO `lyfgeek`.`score` (`s_id`, `c_id`, `s_score`)
VALUES ('07', '03', '98');

sql。

sql 复制代码
-- 查询课程"01"比课程"02"成绩高的学生的信息及课程分数。
-- - in ~ 长型数据变成宽型数据。
SELECT st.*,
       t.s01,
       t.s02
FROM (SELECT sc.`s_id`,
             MAX(CASE
                     WHEN sc.`c_id` = '01' THEN sc.`s_score`
                 END) s01,
             MAX(CASE
                     WHEN sc.`c_id` = '02' THEN sc.`s_score`
                 END) s02
      FROM `score` sc
      GROUP BY sc.`s_id`) t,
     `student` st
WHERE t.s01 > t.s02
  AND t.`s_id` = st.`s_id`;

-- 自连接。
SELECT st.*,
       sc1.`s_score`,
       sc2.`s_score`
FROM `student` st,
     `score` sc1,
     `score` sc2
WHERE st.`s_id` = sc1.`s_id`
  AND sc1.`s_id` = sc2.`s_id`
  AND sc1.`c_id` = '01'
  AND sc2.`c_id` = '02'
  AND sc1.`s_score` > sc2.`s_score`;


-- 2、查询课程"01"比课程"02"成绩低的学生的信息及课程分数。
SELECT `student`.*,
       sc1.`s_score`,
       sc2.`s_score`
FROM `student`
         INNER JOIN
     `score` sc1 ON `student`.`s_id` = sc1.`s_id`
         AND sc1.`c_id` = '01'
         INNER JOIN
     `score` sc2 ON sc1.`s_id` = sc2.`s_id`
         AND sc2.`c_id` = '02'
WHERE sc1.`s_score` < sc2.`s_score`
   OR sc1.`s_score` IS NULL;


-- 3、查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩。
-- 子查询方法。
SELECT sc.`s_id`,
       (SELECT `s_name`
        FROM `student` st
        WHERE st.`s_id` = sc.`s_id`) AS s_name,
       AVG(sc.`s_score`)                avg_score
FROM `score` sc
GROUP BY sc.`s_id`
HAVING avg_score >= 60;

-- 两个表连接方法。
SELECT st.`s_id`,
       st.`s_name`,
       AVG(sc.`s_score`)
FROM `student` st,
     `score` sc
WHERE st.`s_id` = sc.`s_id`
GROUP BY st.`s_id`
HAVING AVG(sc.`s_score` >= 60);


-- 4、查询平均成绩小于 60 分的同学的学生编号和学生姓名和平均成绩。
-- (包括有成绩的和无成绩的)。
SELECT st.`s_id`,
       st.`s_name`,
       AVG(sc.`s_score`) AS avg_score
FROM `student` st,
     `score` sc
WHERE st.`s_id` = sc.`s_id`
GROUP BY sc.`s_id`
HAVING AVG(sc.`s_score`) < 60
UNION
SELECT st.`s_id`,
       st.`s_name`,
       0 AS avg_score
FROM `student` st
WHERE st.`s_id` NOT IN (SELECT DISTINCT `s_id`
                        FROM `score`);


-- 5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩。
SELECT st.`s_id`,
       st.`s_name`,
       COUNT(sc.s_id)               AS sum_course,
       IFNULL(SUM(sc.`s_score`), 0) AS sum_score
FROM `student` st
         LEFT OUTER JOIN
     `score` sc ON st.`s_id` = sc.`s_id`
GROUP BY st.`s_id`;


-- 6、查询"李"姓老师的数量。
SELECT COUNT(`t_id`)
FROM `teacher`
WHERE `t_name` LIKE '李%';


-- 7、查询学过"张三"老师授课的同学的信息。
SELECT st.*
FROM `student` st
         JOIN
     `score` sc ON st.`s_id` = sc.`s_id`
WHERE sc.`c_id` IN (SELECT `c_id`
                    FROM `course`
                    WHERE `t_id` = (SELECT `t_id`
                                    FROM `teacher`
                                    WHERE `t_name` = '老师 1'));

SELECT st.*
FROM `student` st
         INNER JOIN
     `score` sc ON st.`s_id` = sc.`s_id`
WHERE sc.`c_id` IN (SELECT `c_id`
                    FROM `course` c
                             INNER JOIN
                         `teacher` t ON c.`t_id` = t.`t_id`
                    WHERE `t`.`t_name` = '老师 1');


-- 8、查询没学过"张三"老师授课的同学的信息。
SELECT *
FROM `student` st
WHERE st.s_id NOT IN (SELECT st.`s_id`
                      FROM `student` st
                               JOIN
                           `score` sc ON st.`s_id` = sc.`s_id`
                      WHERE sc.`c_id` IN (SELECT `c_id`
                                          FROM `course`
                                          WHERE `t_id` = (SELECT `t_id`
                                                          FROM `teacher`
                                                          WHERE `t_name` = '老师 1')));

SELECT *
FROM `student`
WHERE `s_id` NOT IN (SELECT sc.`s_id`
                     FROM `teacher` t,
                          `score` sc,
                          `course` c
                     WHERE t.`t_id` = c.`t_id`
                       AND c.`c_id` = sc.`c_id`
                       AND t.`t_name` = '老师 1');

SELECT *
FROM `student`
WHERE NOT EXISTS(SELECT 1
                 FROM (SELECT sc.`s_id`
                       FROM `teacher` t,
                            `score` sc,
                            `course` c
                       WHERE t.`t_id` = c.`t_id`
                         AND c.`c_id` = sc.`c_id`
                         AND t.`t_name` = '老师 1') t
                 WHERE t.s_id = student.s_id);


-- 9、查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息。
SELECT st.*
FROM `student` st,
     `score` sc1,
     `score` sc2
WHERE st.`s_id` = sc1.`s_id`
  AND st.`s_id` = sc2.`s_id`
  AND sc1.`c_id` = '01'
  AND sc2.`c_id` = '02';


-- 10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息。
SELECT st.*
FROM `student` st
WHERE st.`s_id` IN (SELECT `s_id`
                    FROM `score`
                    WHERE `c_id` = '01')
  AND st.`s_id` NOT IN (SELECT `s_id`
                        FROM `score`
                        WHERE `c_id` = '02');

SELECT st.*
FROM `student` st,
     (SELECT `s_id`,
             MAX(IF(`c_id` = '01', `s_score`, NULL)) s01,
             MAX(IF(`c_id` = '02', `s_score`, NULL)) s02
      FROM `score`
      GROUP BY `s_id`) t
WHERE t.`s_id` = st.`s_id`
  AND t.s01 IS NOT NULL
  AND t.s02 IS NULL;


-- 11、查询没有学全所有课程的同学的信息。
SELECT st.*,
       COUNT(sc.`c_id`) count_sc
FROM `student` st
         LEFT JOIN
     `score` sc ON st.`s_id` = sc.`s_id`
GROUP BY st.`s_id`
HAVING COUNT(sc.`c_id`) < (SELECT COUNT(`c_id`)
                           FROM `course`);

SELECT st.*
FROM `student` st
WHERE st.`s_id` IN (SELECT `s_id`
                    FROM `score`
                    WHERE `s_id` NOT IN (SELECT sc1.`s_id`
                                         FROM `score` sc1
                                                  JOIN
                                              `score` sc2 ON sc1.`s_id` = sc2.`s_id`
                                                  AND sc2.`c_id` = '02'
                                                  JOIN
                                              `score` sc3 ON sc1.`s_id` = sc3.`s_id`
                                                  AND sc3.`c_id` = '03'
                                         WHERE sc1.`c_id` = '01'));


-- 12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息。
SELECT *
FROM `student`
WHERE `s_id` IN (SELECT DISTINCT `s_id`
                 FROM `score`
                 WHERE `c_id` IN (SELECT `c_id`
                                  FROM `score`
                                  WHERE `s_id` = '01'))
GROUP BY 1, 2, 3, 4;
-- 第 1 2 3 4 字段。


-- 13、查询和"01"号的同学学习的课程完全相同的其他同学的信息。

-- 创建 01 所学临时表。
CREATE TABLE s01_sc_temp AS
SELECT t1.*, sc.`c_id` cid2
FROM (SELECT st.*,
             t2.`c_id`
      FROM `student` st,
           (SELECT `c_id`
            FROM `score`
            WHERE `s_id` = '01') t2) t1
         LEFT JOIN
     `score` sc ON t1.`s_id` = sc.`s_id`
         AND t1.`c_id` = sc.`c_id`
UNION
SELECT t.*,
       sc.`c_id` cid2
FROM (SELECT st.*,
             b.`c_id`
      FROM `student` st,
           (SELECT `c_id`
            FROM `score`
            WHERE `s_id` = '01') b) t
         RIGHT JOIN
     `score` sc ON t.`s_id` = sc.`s_id`
         AND t.`c_id` = sc.`c_id`;

SELECT *
FROM `student`
WHERE `s_id` NOT IN (SELECT `s_id`
                     FROM s01_s_temp
                     WHERE cid2 IS NULL
                        OR `c_id` IS NULL)
  AND `s_id` != '01';

-- ~ ~ ~

SELECT *
FROM `student`
WHERE `s_id` IN (SELECT DISTINCT `s_id`
                 FROM `score`
                 WHERE `s_id` != '01'
                   AND `c_id` IN (SELECT `c_id`
                                  FROM `score`
                                  WHERE `s_id` = '01')
                 GROUP BY `s_id`
                 HAVING COUNT(1) = (SELECT COUNT(1)
                                    FROM `score`
                                    WHERE `s_id` = '01'));


-- 14、查询没学过"张三"老师讲授的任一门课程的学生姓名。
SELECT st.`s_name`
FROM `student` st
WHERE st.`s_id` NOT IN (SELECT `s_id`
                        FROM `score`
                        WHERE `c_id` = (SELECT `c_id`
                                        FROM `course`
                                        WHERE `t_id` = (SELECT `t_id`
                                                        FROM `teacher`
                                                        WHERE `t_name` = '老师 1'))
                        GROUP BY s_id);


-- 15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩。
SELECT st.`s_id`,
       st.`s_name`,
       AVG(sc.`s_score`) avg_score
FROM `student` st
         LEFT JOIN
     `score` sc ON st.`s_id` = sc.`s_id`
GROUP BY st.`s_id`
HAVING SUM(IF(sc.`s_score` >= 60, 0, 1)) >= 2;

SELECT st.`s_id`,
       st.`s_name`,
       AVG(sc.`s_score`) avg_score
FROM `student` st
         LEFT JOIN
     `score` sc ON st.`s_id` = sc.`s_id`
GROUP BY st.`s_id`
HAVING SUM(IF(sc.`s_score` >= 60, 0, 1)) >= 2;

SELECT st.`s_id`,
       st.`s_name`,
       ROUND(AVG(sc.`s_score`))
FROM student st
         LEFT JOIN
     score sc ON st.`s_id` = sc.`s_id`
WHERE st.`s_id` IN (SELECT `s_id`
                    FROM `score`
                    WHERE `s_score` < 60
                    GROUP BY `s_id`
                    HAVING COUNT(1) >= 2)
GROUP BY st.`s_id`, st.`s_name`;


-- 16、检索课程"01"分数小于 60,按分数降序排列的学生信息。
SELECT st.*,
       sc.`s_score`
FROM `score` sc
         RIGHT JOIN
     `student` st ON sc.`s_id` = st.`s_id`
WHERE sc.`c_id` = '01'
  AND sc.`s_score` < 60
ORDER BY `s_score` DESC;

SELECT st.*,
       sc.`c_id`,
       sc.`s_score`
FROM `student` st,
     `score` sc
WHERE st.`s_id` = sc.`s_id`
  AND sc.`c_id` = '01'
  AND sc.`s_score` < 60
ORDER BY sc.`s_score` DESC;


-- 17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩。
SELECT sc.`s_id`,
       (SELECT `s_score`
        FROM `score`
        WHERE `s_id` = sc.`s_id`
          AND `c_id` = '01')    AS 语文,
       (SELECT `s_score`
        FROM `score`
        WHERE `s_id` = sc.`s_id`
          AND `c_id` = '02')    AS 数学,
       (SELECT `s_score`
        FROM `score`
        WHERE `s_id` = sc.`s_id`
          AND `c_id` = '03')    AS 英语,
       ROUND(AVG(`s_score`), 2) AS 平均分
FROM `score` sc
GROUP BY sc.`s_id`
ORDER BY 平均分 DESC;


-- 18.查询各科成绩最高分、最低分和平均分,以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率。
-- 及格为 >= 60,中等为:70 ~ 80,优良为:80 ~ 90,优秀为:>= 90。
SELECT sc.`c_id`,
       c.`c_name`,
       MAX(`s_score`),
       MIN(`s_score`),
       ROUND(AVG(`s_score`), 2),
       ROUND(100 * (SUM(IF(sc.`s_score` >= 60, 1, 0)) / SUM(IF(sc.`s_score`, 1, 0))),
             2) AS 及格率,
       ROUND(100 * (SUM(IF(sc.`s_score` >= 70 AND sc.`s_score` <= 80, 1, 0)) / SUM(IF(sc.`s_score`, 1, 0))),
             2) AS 中等率,
       ROUND(100 * (SUM(IF(sc.`s_score` >= 80 AND sc.`s_score` <= 90, 1, 0)) / SUM(IF(sc.`s_score`, 1, 0))),
             2) AS 优良率,
       ROUND(100 * (SUM(IF(sc.`s_score` >= 90, 1, 0)) / SUM(IF(sc.`s_score`, 1, 0))),
             2) AS 优秀率
FROM `score` sc
         LEFT JOIN
     `course` c ON sc.`c_id` = c.`c_id`
GROUP BY sc.`c_id`, c.`c_name`;


-- 19、按各科成绩进行排序,并显示排名(实现不完全)。
-- mysql 没有 rank(); 函数。
SELECT sc1.`c_id`,
       sc1.`s_id`,
       sc1.`s_score`,
       COUNT(sc2.`s_score`) + 1 AS `rank`
FROM `score` sc1
         LEFT JOIN
     `score` sc2 ON sc1.`s_score` < sc2.`s_score`
         AND sc1.`c_id` = sc2.`c_id`
GROUP BY sc1.`c_id`, sc1.`s_id`, sc1.`s_score`
ORDER BY sc1.`c_id`, `rank`;


-- 20、查询学生的总成绩并进行排名。
SELECT t1.`s_id`,
       @i := @i + 1                              AS i,
       @k := (IF(@score = t1.sum_score, @k, @i)) AS `rank`,
       @score := t1.sum_score                    AS score
FROM (SELECT `s_id`,
             SUM(`s_score`) AS sum_score
      FROM `score`
      GROUP BY `s_id`
      ORDER BY sum_score DESC) t1,
     (SELECT @k := 0, @i := 0, @score := 0) AS kis;


-- 21、查询不同老师所教不同课程平均分从高到低显示。
SELECT c.`t_id`,
       t.`t_name`,
       c.`c_id`,
       ROUND(AVG(`s_score`), 2) AS avg_score
FROM `course` c
         LEFT JOIN
     `score` sc ON c.`c_id` = sc.`c_id`
         LEFT JOIN
     `teacher` t ON c.`t_id` = t.`t_id`
GROUP BY c.`c_id`, c.`t_id`, t.`t_name`
ORDER BY avg_score DESC;


-- 22、查询所有课程的成绩第 2 名到第 3 名的学生信息及该课程成绩。
SELECT d.*,
       si2.排名,
       si2.`s_score`,
       si2.`c_id`
FROM (SELECT sc.`s_id`,
             sc.`s_score`,
             sc.`c_id`,
             @i := @i + 1 AS 排名
      FROM `score` sc,
           (SELECT @i := 0) as i2
      WHERE sc.c_id = '01') as si2
         LEFT JOIN
     student d ON si2.s_id = d.s_id
WHERE 排名 BETWEEN 2 AND 3
UNION
SELECT st.*,
       sj2.排名,
       sj2.s_score,
       sj2.c_id
FROM (SELECT sc.s_id,
             sc.s_score,
             sc.c_id,
             @j := @j + 1 AS 排名
      FROM `score` sc,
           (SELECT @j := 0) as j2
      WHERE sc.c_id = '02') as sj2
         LEFT JOIN
     `student` st ON sj2.s_id = st.s_id
WHERE 排名 BETWEEN 2 AND 3
UNION
SELECT d.*,
       s.排名,
       s.`s_score`,
       s.`c_id`
FROM (SELECT sc.`s_id`,
             sc.`s_score`,
             sc.`c_id`,
             @k := @k + 1 AS 排名
      FROM `score` sc,
           (SELECT @k := 0) as k2
      WHERE sc.`c_id` = '03') as s
         LEFT JOIN
     `student` d ON s.`s_id` = d.`s_id`
WHERE 排名 BETWEEN 2 AND 3;


-- 23、统计各科成绩各分数段人数:课程编号, 课程名称, [100-85], [85-70], [70-60], [0-60] 及所占百分比。
SELECT DISTINCT c.`c_name`,
                sc.`c_id`,
                t1.`85-100`,
                t1.百分比,
                t2.`70-85`,
                t2.百分比,
                t3.`60-70`,
                t3.百分比,
                t4.`0-60`,
                t4.百分比
FROM `score` sc
         LEFT JOIN
     (SELECT `c_id`,
             SUM(IF(`s_score` > 85 AND `s_score` <= 100, 1, 0))                              AS `85-100`,
             ROUND(100 * (SUM(IF(`s_score` > 85 AND `s_score` <= 100, 1, 0)) / COUNT(*)), 2) AS 百分比
      FROM `score`
      GROUP BY `c_id`) t1 ON sc.`c_id` = t1.`c_id`
         LEFT JOIN
     (SELECT `c_id`,
             SUM(IF(`s_score` > 70 AND `s_score` <= 85, 1, 0))                              AS `70-85`,
             ROUND(100 * (SUM(IF(`s_score` > 70 AND `s_score` <= 85, 1, 0)) / COUNT(*)), 2) AS 百分比
      FROM `score`
      GROUP BY `c_id`) t2 ON sc.`c_id` = t2.`c_id`
         LEFT JOIN
     (SELECT `c_id`,
             SUM(IF(`s_score` > 60 AND `s_score` <= 70, 1, 0))                              AS `60-70`,
             ROUND(100 * (SUM(IF(`s_score` > 60 AND `s_score` <= 70, 1, 0)) / COUNT(*)), 2) AS 百分比
      FROM `score`
      GROUP BY `c_id`) t3 ON sc.`c_id` = t3.`c_id`
         LEFT JOIN
     (SELECT `c_id`,
             SUM(IF(`s_score` >= 0 AND `s_score` <= 60, 1, 0))                              AS `0-60`,
             ROUND(100 * (SUM(IF(`s_score` >= 0 AND `s_score` <= 60, 1, 0)) / COUNT(*)), 2) AS 百分比
      FROM `score`
      GROUP BY `c_id`) t4 ON sc.`c_id` = t4.`c_id`
         LEFT JOIN
     `course` c ON sc.`c_id` = c.`c_id`;


-- 24、查询学生平均成绩及其名次。
SELECT t.`s_id`,
       @i := @i + 1                                 AS '不保留空缺排名',
       @k := (IF(@avg_score = t.avg_score, @k, @i)) AS '保留空缺排名',
       @avg_score := avg_score                      AS '平均分'
FROM (SELECT `s_id`,
             ROUND(AVG(`s_score`), 2) AS avg_score
      FROM score
      GROUP BY `s_id`) t,
     (SELECT @avg_score := 0, @i := 0, @k := 0) b;


-- 25、查询各科成绩前三名的记录。
-- - 选出 sc1 表比 sc2 表成绩大的所有组。
-- - 选出比当前 id 成绩大的小于三个的。
SELECT sc1.`s_id`,
       sc1.`c_id`,
       sc1.`s_score`
FROM `score` sc1
         LEFT JOIN
     `score` sc2 ON sc1.`c_id` = sc2.`c_id`
         AND sc1.`s_score` < sc2.`s_score`
GROUP BY sc1.`s_id`, sc1.`c_id`, sc1.`s_score`
HAVING COUNT(sc2.`s_id`) < 3
ORDER BY sc1.`c_id`, sc1.`s_score` DESC;


-- 26、查询每门课程被选修的学生数。
SELECT `c_id`,
       COUNT(`s_id`)
FROM `score`
GROUP BY `c_id`;


-- 27、查询出只有两门课程的全部学生的学号和姓名。
SELECT `s_id`,
       `s_name`
FROM `student`
WHERE `s_id` IN (SELECT `s_id`
                 FROM `score`
                 GROUP BY `s_id`
                 HAVING COUNT(`c_id`) = 2);


-- 28、查询男生、女生人数。
SELECT `s_sex`,
       COUNT(`s_sex`) AS 人数
FROM student
GROUP BY s_sex;


-- 29、查询名字中含有"风"字的学生信息。
SELECT *
FROM `student`
WHERE `s_name` LIKE '%风%';


-- 30、查询同名同性学生名单,并统计同名人数。
SELECT st1.`s_name`,
       st1.`s_sex`,
       COUNT(*)
FROM `student` st1
         JOIN
     `student` st2 ON st1.`s_id` != st2.`s_id`
         AND st1.`s_name` = st2.`s_name`
         AND st1.`s_sex` = st2.`s_sex`
GROUP BY st1.`s_name`, st1.`s_sex`;


-- 31、查询 1990 年出生的学生名单。
SELECT `s_name`
FROM `student`
WHERE `s_birth` LIKE '1990%';


-- 32、查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列。
SELECT `c_id`,
       ROUND(AVG(`s_score`), 2) AS avg_score
FROM `score`
GROUP BY `c_id`
ORDER BY avg_score DESC, `c_id` ASC;


-- 33、查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩。
SELECT sc.`s_id`,
       st.`s_name`,
       ROUND(AVG(sc.`s_score`), 2) AS avg_score
FROM `score` sc
         LEFT JOIN
     `student` st ON sc.`s_id` = st.`s_id`
GROUP BY `s_id`
HAVING avg_score >= 85;


-- 34、查询课程名称为"数学",且分数低于 60 的学生姓名和分数。
SELECT st.`s_name`,
       sc.`s_score`
FROM `score` sc
         LEFT JOIN
     `student` st ON st.`s_id` = sc.`s_id`
WHERE sc.`c_id` = (SELECT `c_id`
                   FROM `course`
                   WHERE `c_name` = '数学')
  AND sc.s_score < 60;


-- 35、查询所有学生的课程及分数情况。
SELECT st.`s_id`,
       st.`s_name`,
       SUM(IF(c.`c_name` = '语文', sc.`s_score`, 0)) AS '语文',
       SUM(IF(c.`c_name` = '数学', sc.`s_score`, 0)) AS '数学',
       SUM(IF(c.`c_name` = '英语', sc.`s_score`, 0)) AS '英语',
       SUM(sc.`s_score`)                             AS '总分'
FROM `student` st
         LEFT JOIN
     `score` sc ON st.`s_id` = sc.`s_id`
         LEFT JOIN
     `course` c ON sc.`c_id` = c.`c_id`
GROUP BY st.`s_id`, st.`s_name`;


-- 36、查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数。
SELECT st.`s_name`,
       c.`c_name`,
       sc.`s_score`
FROM `course` c
         LEFT JOIN
     `score` sc ON c.`c_id` = sc.`c_id`
         LEFT JOIN
     `student` st ON st.`s_id` = sc.`s_id`
WHERE sc.`s_score` >= 70;


-- 37、查询不及格的课程。
SELECT sc.`s_id`,
       sc.`c_id`,
       c.`c_name`,
       sc.`s_score`
FROM `score` sc
         LEFT JOIN
     `course` c ON sc.`c_id` = c.`c_id`
WHERE sc.`s_score` < 60;


-- 38、查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名。
SELECT sc.`s_id`,
       st.`s_name`
FROM `score` sc
         LEFT JOIN
     `student` st ON sc.`s_id` = st.`s_id`
WHERE sc.`c_id` = '01'
  AND sc.`s_score` > 80;


-- 39、求每门课程的学生人数。
SELECT COUNT(*)
FROM `score`
GROUP BY `c_id`;


-- 40、查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩。
-- 查询老师 id。
SELECT `c_id`
FROM `course` c,
     `teacher` t
WHERE c.`t_id` = t.`t_id`
  AND t.`t_name` = '老师 1';
-- 查询最高分(可能有相同分数)。
SELECT MAX(`s_score`)
FROM `score`
WHERE `c_id` = '02';
-- 查询信息。
SELECT st.*,
       sc.`s_score`,
       sc.`c_id`,
       c.`c_name`
FROM `student` st
         LEFT JOIN
     `score` sc ON st.`s_id` = sc.`s_id`
         LEFT JOIN
     `course` c ON sc.`c_id` = c.`c_id`
WHERE sc.`c_id` = (SELECT `c_id`
                   FROM `course` c,
                        `teacher` t
                   WHERE c.`t_id` = t.`t_id`
                     AND t.`t_name` = '老师 1')
  AND sc.s_score IN (SELECT MAX(s_score)
                     FROM score
                     WHERE c_id = '02');

SELECT c.`c_name`, sc.`s_score`, st.*
FROM `course` c,
     `score` sc,
     `teacher` t,
     `student` st
WHERE t.`t_id` = c.`t_id`
  AND c.`c_id` = sc.`c_id`
  AND st.`s_id` = sc.`s_id`
  AND t.`t_name` = '老师 1'
  AND sc.`s_score` IN (SELECT MAX(`s_score`)
                       FROM `course`,
                            `score`,
                            `teacher`,
                            `student`
                       WHERE `teacher`.`t_id` = `course`.`t_id`
                         AND `course`.`c_id` = `score`.`c_id`
                         AND `student`.`s_id` = `score`.`s_id`
                         AND `teacher`.`t_name` = '老师 1');


-- 41、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩。
SELECT DISTINCT sc2.`s_id`,
                sc2.`c_id`,
                sc2.`s_score`
FROM `score` sc1,
     `score` sc2
WHERE sc1.`c_id` != sc2.`c_id`
  AND sc1.`s_score` = sc2.`s_score`;


-- 42、查询每门功成绩最好的前两名。
-- 牛逼的写法。
SELECT sc1.`s_id`,
       sc1.`c_id`,
       sc1.`s_score`
FROM `score` sc1
WHERE (SELECT COUNT(1)
       FROM `score` sc2
       WHERE sc2.`c_id` = sc1.`c_id`
         AND sc2.`s_score` >= sc1.`s_score`) <= 2
ORDER BY sc1.`c_id`;


-- 43、统计每门课程的学生选修人数(超过 5 人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列。
SELECT `c_id`,
       COUNT(*) AS total
FROM `score`
GROUP BY `c_id`
HAVING total > 5
ORDER BY total DESC, `c_id`;


-- 44、检索至少选修两门课程的学生学号。
SELECT `s_id`,
       COUNT(*)
FROM `score`
GROUP BY `s_id`
HAVING COUNT(*) >= 2;


-- 45、查询选修了全部课程的学生信息。
SELECT *
FROM `student`
WHERE `s_id` IN (SELECT `s_id`
                 FROM `score`
                 GROUP BY `s_id`
                 HAVING COUNT(*) = (SELECT COUNT(*)
                                    FROM `course`));


-- 46、查询各学生的年龄。
-- 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一。
SELECT `s_birth`,
       (DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(`s_birth`, '%Y') -
        (IF(DATE_FORMAT(NOW(), '%m%d') > DATE_FORMAT(`s_birth`, '%m%d'),
            0,
            1))) AS age
FROM `student`;


-- 47、查询本周过生日的学生。
SELECT *
FROM `student`
WHERE WEEK(DATE_FORMAT(NOW(), '%Y%m%d')) = WEEK(`s_birth`);

SELECT *
FROM `student`
WHERE YEARWEEK(`s_birth`) = YEARWEEK(DATE_FORMAT(NOW(), '%Y%m%d'));

SELECT WEEK(DATE_FORMAT(NOW(), '%Y%m%d'));


-- 48、查询下周过生日的学生。
SELECT *
FROM `student`
WHERE WEEK(DATE_FORMAT(NOW(), '%Y%m%d')) + 1 = WEEK(`s_birth`);


-- 49、查询本月过生日的学生。
SELECT *
FROM `student`
WHERE MONTH(DATE_FORMAT(NOW(), '%Y%m%d')) = MONTH(`s_birth`);


-- 50、查询下月过生日的学生。
SELECT *
FROM `student`
WHERE MONTH(DATE_FORMAT(NOW(), '%Y-%m-%d')) + 1 = MONTH(`s_birth`);
sql 复制代码
-- 查询课程"01"比课程"02"成绩高的学生的信息及课程分数。
-- - in ~ 长型数据变成宽型数据。
SELECT 
    st.*, t.s01, t.s02
FROM
    (SELECT 
        sc.`s_id`,
            MAX(CASE
                WHEN sc.`c_id` = '01' THEN sc.`s_score`
            END) s01,
            MAX(CASE
                WHEN sc.`c_id` = '02' THEN sc.`s_score`
            END) s02
    FROM
        `score` sc
    GROUP BY sc.`s_id`) t,
    `student` st
WHERE
    t.s01 > t.s02 AND t.`s_id` = st.`s_id`;

-- 自连接。
SELECT 
    st.*, sc1.`s_score`, sc2.`s_score`
FROM
    `student` st,
    `score` sc1,
    `score` sc2
WHERE
    st.`s_id` = sc1.`s_id`
        AND sc1.`s_id` = sc2.`s_id`
        AND sc1.`c_id` = '01'
        AND sc2.`c_id` = '02'
        AND sc1.`s_score` > sc2.`s_score`;


-- 2、查询课程"01"比课程"02"成绩低的学生的信息及课程分数。
SELECT 
    `student`.*, sc1.`s_score`, sc2.`s_score`
FROM
    `student`
        INNER JOIN
    `score` sc1 ON `student`.`s_id` = sc1.`s_id`
        AND sc1.`c_id` = '01'
        INNER JOIN
    `score` sc2 ON sc1.`s_id` = sc2.`s_id`
        AND sc2.`c_id` = '02'
WHERE
    sc1.`s_score` < sc2.`s_score`
        OR sc1.`s_score` IS NULL;


-- 3、查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩。
-- 子查询方法。
SELECT 
    sc.`s_id`,
    (SELECT 
            `s_name`
        FROM
            `student` st
        WHERE
            st.`s_id` = sc.`s_id`) AS s_name,
    AVG(sc.`s_score`) avg_score
FROM
    `score` sc
GROUP BY sc.`s_id`
HAVING avg_score >= 60;

-- 两个表连接方法。
SELECT 
    st.`s_id`, st.`s_name`, AVG(sc.`s_score`)
FROM
    `student` st,
    `score` sc
WHERE
    st.`s_id` = sc.`s_id`
GROUP BY st.`s_id`
HAVING AVG(sc.`s_score` >= 60);


-- 4、查询平均成绩小于 60 分的同学的学生编号和学生姓名和平均成绩。
-- (包括有成绩的和无成绩的)。
SELECT 
    st.`s_id`, st.`s_name`, AVG(sc.`s_score`) AS avg_score
FROM
    `student` st,
    `score` sc
WHERE
    st.`s_id` = sc.`s_id`
GROUP BY sc.`s_id`
HAVING AVG(sc.`s_score`) < 60 
UNION SELECT 
    st.`s_id`, st.`s_name`, 0 AS avg_score
FROM
    `student` st
WHERE
    st.`s_id` NOT IN (SELECT DISTINCT
            `s_id`
        FROM
            `score`);


-- 5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩。
SELECT 
    st.`s_id`,
    st.`s_name`,
    COUNT(sc.s_id) AS sum_course,
    IFNULL(SUM(sc.`s_score`), 0) AS sum_score
FROM
    `student` st
        LEFT OUTER JOIN
    `score` sc ON st.`s_id` = sc.`s_id`
GROUP BY st.`s_id`;


-- 6、查询"李"姓老师的数量。
SELECT 
    COUNT(`t_id`)
FROM
    `teacher`
WHERE
    `t_name` LIKE '李%';


-- 7、查询学过"张三"老师授课的同学的信息。
SELECT 
    st.*
FROM
    `student` st
        JOIN
    `score` sc ON st.`s_id` = sc.`s_id`
WHERE
    sc.`c_id` IN (SELECT 
            `c_id`
        FROM
            `course`
        WHERE
            `t_id` = (SELECT 
                    `t_id`
                FROM
                    `teacher`
                WHERE
                    `t_name` = '老师 1'));

SELECT 
    st.*
FROM
    `student` st
        INNER JOIN
    `score` sc ON st.`s_id` = sc.`s_id`
WHERE
    sc.`c_id` IN (SELECT 
            `c_id`
        FROM
            `course` c
                INNER JOIN
            `teacher` t ON c.`t_id` = t.`t_id`
        WHERE
            `t`.`t_name` = '老师 1');


-- 8、查询没学过"张三"老师授课的同学的信息。
SELECT 
    *
FROM
    `student` st
WHERE
    st.s_id NOT IN (SELECT 
            st.`s_id`
        FROM
            `student` st
                JOIN
            `score` sc ON st.`s_id` = sc.`s_id`
        WHERE
            sc.`c_id` IN (SELECT 
                    `c_id`
                FROM
                    `course`
                WHERE
                    `t_id` = (SELECT 
                            `t_id`
                        FROM
                            `teacher`
                        WHERE
                            `t_name` = '老师 1')));

SELECT 
    *
FROM
    `student`
WHERE
    `s_id` NOT IN (SELECT 
            sc.`s_id`
        FROM
            `teacher` t,
            `score` sc,
            `course` c
        WHERE
            t.`t_id` = c.`t_id`
                AND c.`c_id` = sc.`c_id`
                AND t.`t_name` = '老师 1');

SELECT 
    *
FROM
    `student`
WHERE
    NOT EXISTS( SELECT 
            1
        FROM
            (SELECT 
                sc.`s_id`
            FROM
                `teacher` t, `score` sc, `course` c
            WHERE
                t.`t_id` = c.`t_id`
                    AND c.`c_id` = sc.`c_id`
                    AND t.`t_name` = '老师 1') t
        WHERE
            t.s_id = student.s_id);


-- 9、查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息。
SELECT 
    st.*
FROM
    `student` st,
    `score` sc1,
    `score` sc2
WHERE
    st.`s_id` = sc1.`s_id`
        AND st.`s_id` = sc2.`s_id`
        AND sc1.`c_id` = '01'
        AND sc2.`c_id` = '02';


-- 10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息。
SELECT 
    st.*
FROM
    `student` st
WHERE
    st.`s_id` IN (SELECT 
            `s_id`
        FROM
            `score`
        WHERE
            `c_id` = '01')
        AND st.`s_id` NOT IN (SELECT 
            `s_id`
        FROM
            `score`
        WHERE
            `c_id` = '02');

SELECT 
    st.*
FROM
    `student` st,
    (SELECT 
        `s_id`,
            MAX(IF(`c_id` = '01', `s_score`, NULL)) s01,
            MAX(IF(`c_id` = '02', `s_score`, NULL)) s02
    FROM
        `score`
    GROUP BY `s_id`) t
WHERE
    t.`s_id` = st.`s_id`
        AND t.s01 IS NOT NULL
        AND t.s02 IS NULL;


-- 11、查询没有学全所有课程的同学的信息。
SELECT 
    st.*, COUNT(sc.`c_id`) count_sc
FROM
    `student` st
        LEFT JOIN
    `score` sc ON st.`s_id` = sc.`s_id`
GROUP BY st.`s_id`
HAVING COUNT(sc.`c_id`) < (SELECT 
        COUNT(`c_id`)
    FROM
        `course`);

SELECT 
    st.*
FROM
    `student` st
WHERE
    st.`s_id` IN (SELECT 
            `s_id`
        FROM
            `score`
        WHERE
            `s_id` NOT IN (SELECT 
                    sc1.`s_id`
                FROM
                    `score` sc1
                        JOIN
                    `score` sc2 ON sc1.`s_id` = sc2.`s_id`
                        AND sc2.`c_id` = '02'
                        JOIN
                    `score` sc3 ON sc1.`s_id` = sc3.`s_id`
                        AND sc3.`c_id` = '03'
                WHERE
                    sc1.`c_id` = '01'));


-- 12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息。
SELECT 
    *
FROM
    `student`
WHERE
    `s_id` IN (SELECT DISTINCT
            `s_id`
        FROM
            `score`
        WHERE
            `c_id` IN (SELECT 
                    `c_id`
                FROM
                    `score`
                WHERE
                    `s_id` = '01'))
GROUP BY 1 , 2 , 3 , 4;
-- 第 1 2 3 4 字段。


-- 13、查询和"01"号的同学学习的课程完全相同的其他同学的信息。

-- 创建 01 所学临时表。
CREATE TABLE s01_sc_temp AS SELECT t1.*, sc.`c_id` cid2 FROM
    (SELECT 
        st.*, t2.`c_id`
    FROM
        `student` st, (SELECT 
        `c_id`
    FROM
        `score`
    WHERE
        `s_id` = '01') t2) t1
        LEFT JOIN
    `score` sc ON t1.`s_id` = sc.`s_id`
        AND t1.`c_id` = sc.`c_id` 
UNION SELECT 
    t.*, sc.`c_id` cid2
FROM
    (SELECT 
        st.*, b.`c_id`
    FROM
        `student` st, (SELECT 
        `c_id`
    FROM
        `score`
    WHERE
        `s_id` = '01') b) t
        RIGHT JOIN
    `score` sc ON t.`s_id` = sc.`s_id`
        AND t.`c_id` = sc.`c_id`;

SELECT 
    *
FROM
    `student`
WHERE
    `s_id` NOT IN (SELECT 
            `s_id`
        FROM
            s01_s_temp
        WHERE
            cid2 IS NULL OR `c_id` IS NULL)
        AND `s_id` != '01';

-- ~ ~ ~

SELECT 
    *
FROM
    `student`
WHERE
    `s_id` IN (SELECT DISTINCT
            `s_id`
        FROM
            `score`
        WHERE
            `s_id` != '01'
                AND `c_id` IN (SELECT 
                    `c_id`
                FROM
                    `score`
                WHERE
                    `s_id` = '01')
        GROUP BY `s_id`
        HAVING COUNT(1) = (SELECT 
                COUNT(1)
            FROM
                `score`
            WHERE
                `s_id` = '01'));


-- 14、查询没学过"张三"老师讲授的任一门课程的学生姓名。
SELECT 
    st.`s_name`
FROM
    `student` st
WHERE
    st.`s_id` NOT IN (SELECT 
            `s_id`
        FROM
            `score`
        WHERE
            `c_id` = (SELECT 
                    `c_id`
                FROM
                    `course`
                WHERE
                    `t_id` = (SELECT 
                            `t_id`
                        FROM
                            `teacher`
                        WHERE
                            `t_name` = '老师 1'))
        GROUP BY s_id);


-- 15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩。
SELECT 
    st.`s_id`, st.`s_name`, AVG(sc.`s_score`) avg_score
FROM
    `student` st
        LEFT JOIN
    `score` sc ON st.`s_id` = sc.`s_id`
GROUP BY st.`s_id`
HAVING SUM(IF(sc.`s_score` >= 60, 0, 1)) >= 2;

SELECT 
    st.`s_id`, st.`s_name`, AVG(sc.`s_score`) avg_score
FROM
    `student` st
        LEFT JOIN
    `score` sc ON st.`s_id` = sc.`s_id`
GROUP BY st.`s_id`
HAVING SUM(IF(sc.`s_score` >= 60, 0, 1)) >= 2;

SELECT 
    st.`s_id`, st.`s_name`, ROUND(AVG(sc.`s_score`))
FROM
    student st
        LEFT JOIN
    score sc ON st.`s_id` = sc.`s_id`
WHERE
    st.`s_id` IN (SELECT 
            `s_id`
        FROM
            `score`
        WHERE
            `s_score` < 60
        GROUP BY `s_id`
        HAVING COUNT(1) >= 2)
GROUP BY st.`s_id` , st.`s_name`;


-- 16、检索课程"01"分数小于 60,按分数降序排列的学生信息。
SELECT 
    st.*, sc.`s_score`
FROM
    `score` sc
        RIGHT JOIN
    `student` st ON sc.`s_id` = st.`s_id`
WHERE
    sc.`c_id` = '01' AND sc.`s_score` < 60
ORDER BY `s_score` DESC;

SELECT 
    st.*, sc.`c_id`, sc.`s_score`
FROM
    `student` st,
    `score` sc
WHERE
    st.`s_id` = sc.`s_id`
        AND sc.`c_id` = '01'
        AND sc.`s_score` < 60
ORDER BY sc.`s_score` DESC;


-- 17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩。
SELECT sc.`s_id`,
       (SELECT `s_score`
        FROM `score`
        WHERE `s_id` = sc.`s_id`
          AND `c_id` = '01')    AS 语文,
       (SELECT `s_score`
        FROM `score`
        WHERE `s_id` = sc.`s_id`
          AND `c_id` = '02')    AS 数学,
       (SELECT `s_score`
        FROM `score`
        WHERE `s_id` = sc.`s_id`
          AND `c_id` = '03')    AS 英语,
       ROUND(AVG(`s_score`), 2) AS 平均分
FROM `score` sc
GROUP BY sc.`s_id`
ORDER BY 平均分 DESC;


-- 18.查询各科成绩最高分、最低分和平均分,以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率。
-- 及格为 >= 60,中等为:70 ~ 80,优良为:80 ~ 90,优秀为:>= 90。
SELECT sc.`c_id`,
       c.`c_name`,
       MAX(`s_score`),
       MIN(`s_score`),
       ROUND(AVG(`s_score`), 2),
       ROUND(100 * (SUM(IF(sc.`s_score` >= 60, 1, 0)) / SUM(IF(sc.`s_score`, 1, 0))),
             2) AS 及格率,
       ROUND(100 * (SUM(IF(sc.`s_score` >= 70 AND sc.`s_score` <= 80, 1, 0)) / SUM(IF(sc.`s_score`, 1, 0))),
             2) AS 中等率,
       ROUND(100 * (SUM(IF(sc.`s_score` >= 80 AND sc.`s_score` <= 90, 1, 0)) / SUM(IF(sc.`s_score`, 1, 0))),
             2) AS 优良率,
       ROUND(100 * (SUM(IF(sc.`s_score` >= 90, 1, 0)) / SUM(IF(sc.`s_score`, 1, 0))),
             2) AS 优秀率
FROM `score` sc
         LEFT JOIN
     `course` c ON sc.`c_id` = c.`c_id`
GROUP BY sc.`c_id`, c.`c_name`;


-- 19、按各科成绩进行排序,并显示排名(实现不完全)。
-- mysql 没有 rank(); 函数。
SELECT 
    sc1.`c_id`,
    sc1.`s_id`,
    sc1.`s_score`,
    COUNT(sc2.`s_score`) + 1 AS `rank`
FROM
    `score` sc1
        LEFT JOIN
    `score` sc2 ON sc1.`s_score` < sc2.`s_score`
        AND sc1.`c_id` = sc2.`c_id`
GROUP BY sc1.`c_id` , sc1.`s_id` , sc1.`s_score`
ORDER BY sc1.`c_id` , `rank`;


-- 20、查询学生的总成绩并进行排名。
SELECT 
    t1.`s_id`,
    @i:=@i + 1 AS i,
    @k:=(IF(@score = t1.sum_score, @k, @i)) AS `rank`,
    @score:=t1.sum_score AS score
FROM
    (SELECT 
        `s_id`, SUM(`s_score`) AS sum_score
    FROM
        `score`
    GROUP BY `s_id`
    ORDER BY sum_score DESC) t1,
    (SELECT @k:=0, @i:=0, @score:=0) AS kis;


-- 21、查询不同老师所教不同课程平均分从高到低显示。
SELECT 
    c.`t_id`,
    t.`t_name`,
    c.`c_id`,
    ROUND(AVG(`s_score`), 2) AS avg_score
FROM
    `course` c
        LEFT JOIN
    `score` sc ON c.`c_id` = sc.`c_id`
        LEFT JOIN
    `teacher` t ON c.`t_id` = t.`t_id`
GROUP BY c.`c_id` , c.`t_id` , t.`t_name`
ORDER BY avg_score DESC;


-- 22、查询所有课程的成绩第 2 名到第 3 名的学生信息及该课程成绩。
SELECT d.*,
       si2.排名,
       si2.`s_score`,
       si2.`c_id`
FROM (SELECT sc.`s_id`,
             sc.`s_score`,
             sc.`c_id`,
             @i := @i + 1 AS 排名
      FROM `score` sc,
           (SELECT @i := 0) as i2
      WHERE sc.c_id = '01') as si2
         LEFT JOIN
     student d ON si2.s_id = d.s_id
WHERE 排名 BETWEEN 2 AND 3
UNION
SELECT st.*,
       sj2.排名,
       sj2.s_score,
       sj2.c_id
FROM (SELECT sc.s_id,
             sc.s_score,
             sc.c_id,
             @j := @j + 1 AS 排名
      FROM `score` sc,
           (SELECT @j := 0) as j2
      WHERE sc.c_id = '02') as sj2
         LEFT JOIN
     `student` st ON sj2.s_id = st.s_id
WHERE 排名 BETWEEN 2 AND 3
UNION
SELECT d.*,
       s.排名,
       s.`s_score`,
       s.`c_id`
FROM (SELECT sc.`s_id`,
             sc.`s_score`,
             sc.`c_id`,
             @k := @k + 1 AS 排名
      FROM `score` sc,
           (SELECT @k := 0) as k2
      WHERE sc.`c_id` = '03') as s
         LEFT JOIN
     `student` d ON s.`s_id` = d.`s_id`
WHERE 排名 BETWEEN 2 AND 3;


-- 23、统计各科成绩各分数段人数:课程编号, 课程名称, [100-85], [85-70], [70-60], [0-60] 及所占百分比。
SELECT DISTINCT c.`c_name`,
                sc.`c_id`,
                t1.`85-100`,
                t1.百分比,
                t2.`70-85`,
                t2.百分比,
                t3.`60-70`,
                t3.百分比,
                t4.`0-60`,
                t4.百分比
FROM `score` sc
         LEFT JOIN
     (SELECT `c_id`,
             SUM(IF(`s_score` > 85 AND `s_score` <= 100, 1, 0))                              AS `85-100`,
             ROUND(100 * (SUM(IF(`s_score` > 85 AND `s_score` <= 100, 1, 0)) / COUNT(*)), 2) AS 百分比
      FROM `score`
      GROUP BY `c_id`) t1 ON sc.`c_id` = t1.`c_id`
         LEFT JOIN
     (SELECT `c_id`,
             SUM(IF(`s_score` > 70 AND `s_score` <= 85, 1, 0))                              AS `70-85`,
             ROUND(100 * (SUM(IF(`s_score` > 70 AND `s_score` <= 85, 1, 0)) / COUNT(*)), 2) AS 百分比
      FROM `score`
      GROUP BY `c_id`) t2 ON sc.`c_id` = t2.`c_id`
         LEFT JOIN
     (SELECT `c_id`,
             SUM(IF(`s_score` > 60 AND `s_score` <= 70, 1, 0))                              AS `60-70`,
             ROUND(100 * (SUM(IF(`s_score` > 60 AND `s_score` <= 70, 1, 0)) / COUNT(*)), 2) AS 百分比
      FROM `score`
      GROUP BY `c_id`) t3 ON sc.`c_id` = t3.`c_id`
         LEFT JOIN
     (SELECT `c_id`,
             SUM(IF(`s_score` >= 0 AND `s_score` <= 60, 1, 0))                              AS `0-60`,
             ROUND(100 * (SUM(IF(`s_score` >= 0 AND `s_score` <= 60, 1, 0)) / COUNT(*)), 2) AS 百分比
      FROM `score`
      GROUP BY `c_id`) t4 ON sc.`c_id` = t4.`c_id`
         LEFT JOIN
     `course` c ON sc.`c_id` = c.`c_id`;


-- 24、查询学生平均成绩及其名次。
SELECT t.`s_id`,
       @i := @i + 1                                 AS '不保留空缺排名',
       @k := (IF(@avg_score = t.avg_score, @k, @i)) AS '保留空缺排名',
       @avg_score := avg_score                      AS '平均分'
FROM (SELECT `s_id`,
             ROUND(AVG(`s_score`), 2) AS avg_score
      FROM score
      GROUP BY `s_id`) t,
     (SELECT @avg_score := 0, @i := 0, @k := 0) b;


-- 25、查询各科成绩前三名的记录。
-- - 选出 sc1 表比 sc2 表成绩大的所有组。
-- - 选出比当前 id 成绩大的小于三个的。
SELECT 
    sc1.`s_id`, sc1.`c_id`, sc1.`s_score`
FROM
    `score` sc1
        LEFT JOIN
    `score` sc2 ON sc1.`c_id` = sc2.`c_id`
        AND sc1.`s_score` < sc2.`s_score`
GROUP BY sc1.`s_id` , sc1.`c_id` , sc1.`s_score`
HAVING COUNT(sc2.`s_id`) < 3
ORDER BY sc1.`c_id` , sc1.`s_score` DESC;


-- 26、查询每门课程被选修的学生数。
SELECT 
    `c_id`, COUNT(`s_id`)
FROM
    `score`
GROUP BY `c_id`;


-- 27、查询出只有两门课程的全部学生的学号和姓名。
SELECT 
    `s_id`, `s_name`
FROM
    `student`
WHERE
    `s_id` IN (SELECT 
            `s_id`
        FROM
            `score`
        GROUP BY `s_id`
        HAVING COUNT(`c_id`) = 2);


-- 28、查询男生、女生人数。
SELECT 
    `s_sex`, COUNT(`s_sex`) AS 人数
FROM
    student
GROUP BY s_sex;


-- 29、查询名字中含有"风"字的学生信息。
SELECT 
    *
FROM
    `student`
WHERE
    `s_name` LIKE '%风%';


-- 30、查询同名同性学生名单,并统计同名人数。
SELECT 
    st1.`s_name`, st1.`s_sex`, COUNT(*)
FROM
    `student` st1
        JOIN
    `student` st2 ON st1.`s_id` != st2.`s_id`
        AND st1.`s_name` = st2.`s_name`
        AND st1.`s_sex` = st2.`s_sex`
GROUP BY st1.`s_name` , st1.`s_sex`;


-- 31、查询 1990 年出生的学生名单。
SELECT 
    `s_name`
FROM
    `student`
WHERE
    `s_birth` LIKE '1990%';


-- 32、查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列。
SELECT 
    `c_id`, ROUND(AVG(`s_score`), 2) AS avg_score
FROM
    `score`
GROUP BY `c_id`
ORDER BY avg_score DESC , `c_id` ASC;


-- 33、查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩。
SELECT 
    sc.`s_id`,
    st.`s_name`,
    ROUND(AVG(sc.`s_score`), 2) AS avg_score
FROM
    `score` sc
        LEFT JOIN
    `student` st ON sc.`s_id` = st.`s_id`
GROUP BY `s_id`
HAVING avg_score >= 85;


-- 34、查询课程名称为"数学",且分数低于 60 的学生姓名和分数。
SELECT 
    st.`s_name`, sc.`s_score`
FROM
    `score` sc
        LEFT JOIN
    `student` st ON st.`s_id` = sc.`s_id`
WHERE
    sc.`c_id` = (SELECT 
            `c_id`
        FROM
            `course`
        WHERE
            `c_name` = '数学')
        AND sc.s_score < 60;


-- 35、查询所有学生的课程及分数情况。
SELECT st.`s_id`,
       st.`s_name`,
       SUM(IF(c.`c_name` = '语文', sc.`s_score`, 0)) AS '语文',
       SUM(IF(c.`c_name` = '数学', sc.`s_score`, 0)) AS '数学',
       SUM(IF(c.`c_name` = '英语', sc.`s_score`, 0)) AS '英语',
       SUM(sc.`s_score`)                             AS '总分'
FROM `student` st
         LEFT JOIN
     `score` sc ON st.`s_id` = sc.`s_id`
         LEFT JOIN
     `course` c ON sc.`c_id` = c.`c_id`
GROUP BY st.`s_id`, st.`s_name`;


-- 36、查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数。
SELECT 
    st.`s_name`, c.`c_name`, sc.`s_score`
FROM
    `course` c
        LEFT JOIN
    `score` sc ON c.`c_id` = sc.`c_id`
        LEFT JOIN
    `student` st ON st.`s_id` = sc.`s_id`
WHERE
    sc.`s_score` >= 70;


-- 37、查询不及格的课程。
SELECT 
    sc.`s_id`, sc.`c_id`, c.`c_name`, sc.`s_score`
FROM
    `score` sc
        LEFT JOIN
    `course` c ON sc.`c_id` = c.`c_id`
WHERE
    sc.`s_score` < 60;


-- 38、查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名。
SELECT 
    sc.`s_id`, st.`s_name`
FROM
    `score` sc
        LEFT JOIN
    `student` st ON sc.`s_id` = st.`s_id`
WHERE
    sc.`c_id` = '01' AND sc.`s_score` > 80;


-- 39、求每门课程的学生人数。
SELECT 
    COUNT(*)
FROM
    `score`
GROUP BY `c_id`;


-- 40、查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩。
-- 查询老师 id。
SELECT 
    `c_id`
FROM
    `course` c,
    `teacher` t
WHERE
    c.`t_id` = t.`t_id`
        AND t.`t_name` = '老师 1';
-- 查询最高分(可能有相同分数)。
SELECT 
    MAX(`s_score`)
FROM
    `score`
WHERE
    `c_id` = '02';
-- 查询信息。
SELECT 
    st.*, sc.`s_score`, sc.`c_id`, c.`c_name`
FROM
    `student` st
        LEFT JOIN
    `score` sc ON st.`s_id` = sc.`s_id`
        LEFT JOIN
    `course` c ON sc.`c_id` = c.`c_id`
WHERE
    sc.`c_id` = (SELECT 
            `c_id`
        FROM
            `course` c,
            `teacher` t
        WHERE
            c.`t_id` = t.`t_id`
                AND t.`t_name` = '老师 1')
        AND sc.s_score IN (SELECT 
            MAX(s_score)
        FROM
            score
        WHERE
            c_id = '02');

SELECT 
    c.`c_name`, sc.`s_score`, st.*
FROM
    `course` c,
    `score` sc,
    `teacher` t,
    `student` st
WHERE
    t.`t_id` = c.`t_id`
        AND c.`c_id` = sc.`c_id`
        AND st.`s_id` = sc.`s_id`
        AND t.`t_name` = '老师 1'
        AND sc.s_score IN (SELECT 
            MAX(s_score)
        FROM
            course,
            score,
            teacher,
            student
        WHERE
            teacher.t_id = course.t_id
                AND course.c_id = score.c_id
                AND student.s_id = score.s_id
                AND teacher.t_name = '老师 1');


-- 41、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩。
SELECT DISTINCT
    sc2.`s_id`, sc2.`c_id`, sc2.`s_score`
FROM
    `score` sc1,
    `score` sc2
WHERE
    sc1.`c_id` != sc2.`c_id`
        AND sc1.`s_score` = sc2.`s_score`;


-- 42、查询每门功成绩最好的前两名。
-- 牛逼的写法。
SELECT 
    sc1.`s_id`, sc1.`c_id`, sc1.`s_score`
FROM
    `score` sc1
WHERE
    (SELECT 
            COUNT(1)
        FROM
            `score` sc2
        WHERE
            sc2.`c_id` = sc1.`c_id`
                AND sc2.`s_score` >= sc1.`s_score`) <= 2
ORDER BY sc1.`c_id`;


-- 43、统计每门课程的学生选修人数(超过 5 人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列。
SELECT 
    `c_id`, COUNT(*) AS total
FROM
    `score`
GROUP BY `c_id`
HAVING total > 5
ORDER BY total DESC , `c_id`;


-- 44、检索至少选修两门课程的学生学号。
SELECT 
    `s_id`, COUNT(*)
FROM
    `score`
GROUP BY `s_id`
HAVING COUNT(*) >= 2;


-- 45、查询选修了全部课程的学生信息。
SELECT 
    *
FROM
    `student`
WHERE
    `s_id` IN (SELECT 
            `s_id`
        FROM
            `score`
        GROUP BY `s_id`
        HAVING COUNT(*) = (SELECT 
                COUNT(*)
            FROM
                `course`));


-- 46、查询各学生的年龄。
-- 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一。
SELECT 
    `s_birth`,
    (DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(`s_birth`, '%Y') - (IF(DATE_FORMAT(NOW(), '%m%d') > DATE_FORMAT(`s_birth`, '%m%d'),
        0,
        1))) AS age
FROM
    `student`;


-- 47、查询本周过生日的学生。
SELECT 
    *
FROM
    `student`
WHERE
    WEEK(DATE_FORMAT(NOW(), '%Y%m%d')) = WEEK(`s_birth`);

SELECT 
    *
FROM
    `student`
WHERE
    YEARWEEK(`s_birth`) = YEARWEEK(DATE_FORMAT(NOW(), '%Y%m%d'));

SELECT WEEK(DATE_FORMAT(NOW(), '%Y%m%d'));


-- 48、查询下周过生日的学生。
SELECT 
    *
FROM
    `student`
WHERE
    WEEK(DATE_FORMAT(NOW(), '%Y%m%d')) + 1 = WEEK(`s_birth`);


-- 49、查询本月过生日的学生。
SELECT 
    *
FROM
    `student`
WHERE
    MONTH(DATE_FORMAT(NOW(), '%Y%m%d')) = MONTH(`s_birth`);


-- 50、查询下月过生日的学生。
SELECT 
    *
FROM
    `student`
WHERE
    MONTH(DATE_FORMAT(NOW(), '%Y-%m-%d')) + 1 = MONTH(`s_birth`);
相关推荐
无极程序员44 分钟前
PHP常量
android·ide·android studio
零炻大礼包1 小时前
【SQL server】数据库远程连接配置
数据库
zmgst1 小时前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
令狐少侠20111 小时前
explain执行计划分析 ref_
mysql
随心............1 小时前
python操作MySQL以及SQL综合案例
数据库·mysql
€☞扫地僧☜€1 小时前
docker 拉取MySQL8.0镜像以及安装
运维·数据库·docker·容器
CopyDragon1 小时前
设置域名跨越访问
数据库·sqlite
xjjeffery1 小时前
MySQL 基础
数据库·mysql
写bug的小屁孩1 小时前
前后端交互接口(三)
运维·服务器·数据库·windows·用户界面·qt6.3
恒辉信达1 小时前
hhdb数据库介绍(8-4)
服务器·数据库·mysql