mysql<六>

-- ########## 01、综合练习 ##########

-- 使用的表结构来自前面创建的"教师授课、学生选课并有课程成绩"这个数据库设计
-- studentinfo、teacherinfo、courseinfo、scoreinfo

-- 1、查询姓张的老师的数量
SELECT COUNT(teacherid) AS 姓张的老师的数量
FROM teacherinfo
WHERE teachername LIKE ‘张%‘;

-- 2、查询每门功课选修的学生数量
-- 写法1、使用左连接
SELECT c.`coursename` AS 课程名称, temp.选修的学生数量
FROM courseinfo AS c
LEFT JOIN
(
    SELECT courseid, COUNT(studentid) AS 选修的学生数量
    FROM scoreinfo
    GROUP BY courseid
) AS temp
ON c.courseid = temp.courseid;
-- 写法2、使用子查询
SELECT
    c.`coursename` AS 课程名称,
    (
        SELECT COUNT(studentid)
        FROM scoreinfo AS sc
        WHERE sc.courseid = c.`courseid`
    ) AS 选修的学生数量
FROM courseinfo AS c;

-- 3、查询个人平均成绩高于60分的学生编号、学生姓名 和 个人平均成绩(如果得到的人数超过2人,显示第二条记录和第三条记录)
SELECT temp.studentid AS 学生编号, s.studentname AS 学生姓名, temp.个人平均成绩
FROM
(
    SELECT studentid, AVG(score) AS 个人平均成绩
    FROM scoreinfo
    GROUP BY studentid
    HAVING AVG(score) > 60
) AS temp
LEFT JOIN studentinfo AS s
ON temp.studentid = s.studentid
LIMIT 1, 2;

-- 4、查询男生的人数 和 女生的人数
SELECT studentgender AS 性别, COUNT(studentid) AS 人数
FROM studentinfo
GROUP BY studentgender;

-- 5、查询同名同姓的学生人数
SELECT * FROM studentinfo;
INSERT INTO studentinfo VALUES(NULL, ‘甄姬‘, ‘女‘, 38);

SELECT studentname AS 重名学生姓名, COUNT(studentid) AS 重名学生人数
FROM studentinfo
GROUP BY studentname
HAVING COUNT(studentid) > 1;

-- 6、查询每门功课的平均成绩,结果按每门功课平均成绩升序排列,成绩相同时,按课程编号倒序排列
SELECT c.`coursename` AS 课程名称, temp.平均成绩
FROM courseinfo AS c
LEFT JOIN
(
    SELECT courseid, AVG(score) AS 平均成绩
    FROM scoreinfo
    GROUP BY courseid
) AS temp
ON c.courseid = temp.courseid
ORDER BY temp.平均成绩 ASC, c.`courseid` DESC;

-- 7、查询课程名称为数学,且数学成绩低于60分的学生姓名和分数
SELECT c.`coursename` AS 课程名称, s.`studentname` AS 学生姓名, sc.`score` AS 分数
FROM scoreinfo AS sc
INNER JOIN courseinfo AS c ON sc.courseid = c.courseid AND c.coursename = ‘数学‘ AND sc.score < 60
INNER JOIN studentinfo AS s ON sc.studentid = s.studentid;

-- 8、查询所有学生的选课信息(显示为:学生编号、学生姓名、课程名称,并单行显示)
SELECT temp.学生编号, temp.学生姓名, GROUP_CONCAT(temp.课程名称) AS 课程名称
FROM
(
    SELECT s.`studentid` AS 学生编号, s.`studentname` AS 学生姓名, c.`coursename` AS 课程名称
    FROM studentinfo AS s
    LEFT JOIN scoreinfo AS sc ON s.studentid = sc.studentid
    LEFT JOIN courseinfo AS c ON sc.courseid = c.courseid
) AS temp
GROUP BY temp.学生编号;

-- 9、查询任何一门课程成绩在60分以上的学生姓名、课程名称及成绩
SELECT s.`studentname` AS 学生姓名, c.`coursename` AS 课程名称, sc.`score` AS 分数
FROM scoreinfo AS sc
INNER JOIN courseinfo AS c ON sc.courseid = c.courseid
INNER JOIN studentinfo AS s ON sc.studentid = s.studentid
WHERE sc.score > 60;

-- 10、查询至少选修了两门课程的学生信息
-- 写法1、使用独立子查询
SELECT s.`studentid` AS 学生编号, s.`studentname` AS 学生姓名, s.`studentgender` AS 学生性别, s.`studentage` AS 学生年龄
FROM studentinfo AS s
WHERE s.studentid IN
(
    SELECT studentid
    FROM scoreinfo
    GROUP BY studentid
    HAVING COUNT(courseid) >= 2
);
-- 写法2、使用内连接
SELECT s.`studentid` AS 学生编号, s.`studentname` AS 学生姓名, s.`studentgender` AS 学生性别, s.`studentage` AS 学生年龄
FROM studentinfo AS s
INNER JOIN
(
    SELECT studentid
    FROM scoreinfo
    GROUP BY studentid
    HAVING COUNT(courseid) >= 2
) AS temp
ON s.studentid = temp.studentid;

-- 11、查询全部学生都选修了的课程编号以及课程名称(基于无脏数据)
SELECT courseid AS 课程编号, coursename AS 课程名称
FROM courseinfo
WHERE courseid IN
(
    -- 在成绩信息表中,按课程编号分组,统计每组的学生编号数量,看看哪组的数量和学生信息表中学生数量一致,一致就说明是全部学生都选修的课程
    SELECT courseid
    FROM scoreinfo
    GROUP BY courseid
    HAVING COUNT(studentid) = (SELECT COUNT(studentid) FROM studentinfo)
);

-- 12、查询个人的英语成绩比数学成绩高的学生信息
-- 思路:在成绩信息表中对行数据进行获取比较,操作起来比较麻烦
--          考虑进行【行转列】的操作,这样就可以在一行中对不同的列的内容进行比较
--          【行转列】技巧:从成绩信息表中通过课程名称对应的课程编号形成两个独立的集合,再把这两个集合根据学生编号进行内连接,
--                          这样就得到同一个学生的不同课程的新集合,即得到同一行中有不同课程成绩的新集合
SELECT s.`studentid` AS 学生编号, s.`studentname` AS 学生姓名, s.`studentgender` AS 学生性别, s.`studentage` AS 学生年龄
FROM studentinfo AS s
WHERE s.`studentid` IN
(
    SELECT temp1.studentid
    FROM
    (
    -- 从成绩信息表中获取的个人英语成绩集合
    SELECT studentid, score
    FROM scoreinfo
    WHERE courseid = (SELECT courseid FROM courseinfo WHERE coursename = ‘英语‘)
    ) AS temp1
    INNER JOIN
    (
    -- 从成绩信息表中获取的个人数学成绩集合
    SELECT studentid, score
    FROM scoreinfo
    WHERE courseid = (SELECT courseid FROM courseinfo WHERE coursename = ‘数学‘)
    ) AS temp2
    ON temp1.studentid = temp2.studentid AND temp1.score > temp2.score
);

-- 13、查询所有学生的编号、姓名、选课数量、总成绩
SELECT s.`studentid` AS 学生编号, s.`studentname` AS 学生姓名, COUNT(sc.`courseid`) AS 选课数量, SUM(sc.`score`) AS 总成绩
FROM studentinfo AS s
LEFT JOIN scoreinfo AS sc ON s.studentid = sc.studentid
-- 按照学生编号进行分组,语法OK
GROUP BY s.studentid;
-- 按照学生编号 和 学生姓名进行分组,语法也OK,因为studentid是主键,久可以唯一标识记录了,加上studentname属于锦上添花
-- GROUP BY s.studentid, s.`studentname`;
-- 按照学生姓名进行分组,语法就不OK了,因为学生姓名有重名时,就会分到一组中了
-- group by s.studentname;

-- 14、查询没有选修过张老师课程的学生信息
-- 思路:没有选修过张老师课程的学生有两种:选修了课程但是选的不是张老师的课程的学生  和 没有选修课程的学生
--          这里正向思考比较麻烦,所以考虑逆向思考
--          从学生集合中剔除那些选修了张老师课程的学生,剩下的就是没有选修张老师课程的学生
SELECT s.`studentid` AS 学生编号, s.`studentname` AS 学生姓名, s.`studentgender` AS 学生性别, s.`studentage` AS 学生年龄
FROM studentinfo AS s
WHERE s.studentid NOT IN
(
    -- 选修了张老师课程的学生
    SELECT sc.studentid
    FROM scoreinfo AS sc
    INNER JOIN courseinfo AS c ON sc.courseid = c.courseid
    INNER JOIN teacherinfo AS t ON c.teacherid = t.teacherid AND t.teachername = ‘张老师‘
);

-- 15、查询学过语文也学过数学的学生信息
SELECT s.`studentid` AS 学生编号, s.`studentname` AS 学生姓名, s.`studentgender` AS 学生性别, s.`studentage` AS 学生年龄
FROM studentinfo AS s
INNER JOIN scoreinfo AS sc1
ON s.studentid = sc1.studentid AND sc1.courseid = (SELECT courseid FROM courseinfo WHERE coursename = ‘语文‘)
INNER JOIN scoreinfo AS sc2
ON s.studentid = sc2.studentid AND sc2.courseid = (SELECT courseid FROM courseinfo WHERE coursename = ‘数学‘);

-- 16、查询个人成绩中每门功课都不及格的学生信息
-- 可能性1、无成绩的也算满足条件
SELECT s.`studentid` AS 学生编号, s.`studentname` AS 学生姓名, s.`studentgender` AS 学生性别, s.`studentage` AS 学生年龄
FROM studentinfo AS s
WHERE s.studentid NOT IN
(
    SELECT studentid
    FROM scoreinfo
    WHERE score >= 60
);
-- 可能性2、无成绩的不算满足条件
SELECT s.`studentid` AS 学生编号, s.`studentname` AS 学生姓名, s.`studentgender` AS 学生性别, s.`studentage` AS 学生年龄
FROM studentinfo AS s
WHERE s.studentid IN
(
    -- 如下写法不正确:因为这样会把部分课程不及格部分课程及格的同学也筛选出来
    -- SELECT studentid
    --     FROM scoreinfo
    --     WHERE score < 60

    -- 正确写法:按照学生编号分组,分组后组里最高的课程分数还小于60分,意味着所有课程都不及格
    SELECT studentid
    FROM scoreinfo
    GROUP BY studentid
    HAVING MAX(score) < 60
);

-- 17、查询每门功课的分数段人数,显示为:课程编号、课程名称、选课人数、[优秀90~100]、[良好80~90]、[一般70~80]、[及格60~70]、[不及格0~60]
SELECT
    sc.`courseid` AS 课程编号,
    c.`coursename` AS 课程名称,
    COUNT(sc.`studentid`) AS 选课人数,
    SUM(CASE WHEN sc.score >= 90 AND sc.score <= 100 THEN 1 ELSE 0 END) AS `[优秀90~100]`,
    SUM(CASE WHEN sc.score >= 80 AND sc.score < 90 THEN 1 ELSE 0 END) AS `[良好80~90]`,
    SUM(CASE WHEN sc.score >= 70 AND sc.score < 80 THEN 1 ELSE 0 END) AS `[一般70~80]`,
    SUM(CASE WHEN sc.score >= 60 AND sc.score < 70 THEN 1 ELSE 0 END) AS `[及格60~70]`,
    SUM(CASE WHEN sc.score >= 0 AND sc.score < 60 THEN 1 ELSE 0 END) AS `[不及格0~60]`
FROM scoreinfo AS sc
INNER JOIN courseinfo AS c ON sc.`courseid` = c.`courseid`
GROUP BY sc.`courseid`;

-- 18、查询没有选修全部课程的学生信息
SELECT s.`studentid` AS 学生编号, s.`studentname` AS 学生姓名, s.`studentgender` AS 学生性别, s.`studentage` AS 学生年龄
FROM studentinfo AS s
WHERE s.studentid IN
(
    -- 按照学生编号分组,每组中的课程统计数量小于课程信息表中课程数量的就是没有选修全部课程的学生
    SELECT studentid
    FROM scoreinfo
    GROUP BY studentid
    HAVING COUNT(courseid) < (SELECT COUNT(courseid) FROM courseinfo)
);

-- 19、查询和刘备(学生编号1)至少一起选修了一门课程的学生编号和学生姓名
SELECT s.`studentid` AS 学生编号, s.`studentname` AS 学生姓名, s.`studentgender` AS 学生性别, s.`studentage` AS 学生年龄
FROM studentinfo AS s
WHERE s.studentid IN
(
    -- 至少和刘备一起选修了一门课程
    SELECT studentid
    FROM scoreinfo
    WHERE courseid IN
    (
        -- 查询出刘备选的课程
        SELECT courseid
        FROM scoreinfo AS sc
        INNER JOIN studentinfo AS s
        ON s.`studentid` = sc.`studentid` AND s.`studentid` = 1 AND s.`studentname` = ‘刘备‘
    )
);

-- 20、查询和张飞(学生编号3)选修的课程完全相同的学生编号和学生姓名
-- 思路:
-- 1)首先制作两个成绩信息表的连接,右表为张飞(学生编号3)的课程及成绩
--       此时会得到 完全和张飞课程相同的同学 和 部分和张飞课程相同的同学
SELECT *
FROM scoreinfo AS sc1
INNER JOIN scoreinfo AS sc2 ON sc1.`courseid` = sc2.`courseid` AND sc2.`studentid` = 3 AND sc1.`studentid` <> sc2.`studentid`
-- 2)在此基础上,在新生成的集合中按照学生编号进行分组,如果有学生的课程数量和张飞的课程数量一致的,那就张飞(学生编号3)选修的课程完全相同的学生
SELECT s.`studentid` AS 学生编号, s.`studentname` AS 学生姓名, s.`studentgender` AS 学生性别, s.`studentage` AS 学生年龄
FROM studentinfo AS s
WHERE s.studentid IN
(
    SELECT sc1.`studentid`
    FROM scoreinfo AS sc1
    INNER JOIN scoreinfo AS sc2 ON sc1.`courseid` = sc2.`courseid` AND sc2.`studentid` = 3 AND sc1.`studentid` <> sc2.`studentid`
    GROUP BY sc1.`studentid`, sc2.`studentid`
    HAVING COUNT(sc1.`courseid`) = (SELECT COUNT(courseid) FROM scoreinfo WHERE studentid = 3)
);

-- 21、按个人平均成绩降序排列显示学生的语文、数学、英语三门功课的成绩(选修了几门计算几门的平均分,未选修的课程显示未选)
--        显示为:学生编号、学生姓名、平均成绩、语文成绩、数学成绩、英语成绩
SELECT
    sc.`studentid` AS 学生编号,
    s.`studentname` AS 学生姓名,
    AVG(sc.`score`) AS 平均成绩,
    IFNULL((
            SELECT sc1.score
            FROM scoreinfo AS sc1
            WHERE sc1.studentid = sc.`studentid`
            AND sc1.courseid = (SELECT courseid FROM courseinfo WHERE coursename = ‘语文‘))
    , ‘未选‘) AS 语文成绩,
    IFNULL((
            SELECT sc2.score
            FROM scoreinfo AS sc2
            WHERE sc2.studentid = sc.`studentid`
            AND sc2.courseid = (SELECT courseid FROM courseinfo WHERE coursename = ‘数学‘))
    , ‘未选‘) AS 数学成绩,
    IFNULL((
            SELECT sc3.score
            FROM scoreinfo AS sc3
            WHERE sc3.studentid = sc.`studentid`
            AND sc3.courseid = (SELECT courseid FROM courseinfo WHERE coursename = ‘英语‘))
    , ‘未选‘) AS 英语成绩
FROM scoreinfo AS sc
INNER JOIN studentinfo AS s
ON sc.`studentid` = s.`studentid`
GROUP BY sc.`studentid`
-- order by AVG(sc.`score`) desc;
-- 上面写法和下面写法均可,因为ORDER BY子句在SELECT子句之后执行的
ORDER BY 平均成绩 DESC;

-- 22、查询每门功课的最高分和最低分,显示为:课程编号、课程名称、最高分、最低分
SELECT
    sc.courseid AS 课程编号,
    c.`coursename` AS 课程名称,
    MAX(sc.`score`) AS 最高分,
    MIN(sc.`score`) AS 最低分
FROM scoreinfo AS sc
INNER JOIN courseinfo AS c
ON sc.courseid = c.courseid
GROUP BY sc.courseid;

-- 23、查询只选修了一门课程的学生的学生编号和学生姓名
SELECT
    sc.`studentid` AS 学生编号,
    s.`studentname` AS 学生姓名
FROM scoreinfo AS sc
INNER JOIN studentinfo AS s
ON sc.studentid = s.studentid
GROUP BY sc.studentid
HAVING COUNT(sc.courseid) = 1;

-- 24、查询学过张老师教的全部课程的学生的学生编号和学生姓名
SELECT
    sc.`studentid` AS 学生编号,
    s.`studentname` AS 学生姓名
FROM scoreinfo AS sc
INNER JOIN courseinfo AS c ON sc.courseid = c.courseid
INNER JOIN teacherinfo AS t ON c.teacherid = t.teacherid AND t.teachername = ‘张老师‘
INNER JOIN studentinfo AS s ON sc.studentid = s.studentid
GROUP BY sc.studentid
HAVING COUNT(sc.courseid) = (
    -- 张老师教的课程数量
    SELECT COUNT(courseinfo.`courseid`)
    FROM courseinfo
    INNER JOIN teacherinfo AS t ON courseinfo.teacherid = t.teacherid AND t.teachername = ‘张老师‘
);

-- 25、学生信息表中被人删除了若干条记录,现在需要查询出第4行至第6行的记录来使用(考虑使用多种实现方式,提示:使用LIMIT 和 不使用LIMIT)
-- delete from studentinfo where studentid = 3 or studentid = 7;

-- 写法1、直接使用LIMIT关键字
SELECT * FROM studentinfo LIMIT 3, 3;

-- 写法2、考虑取出前6行,进行倒序排列,再取出前3行,再倒序
SELECT *
FROM
(
    SELECT *
    FROM
    (
        SELECT *
        FROM (SELECT * FROM studentinfo LIMIT 0, 6) AS temp1
        ORDER BY temp1.studentid DESC
    ) AS temp2 LIMIT 0, 3
) AS temp3
ORDER BY temp3.studentid ASC;

-- 写法3、不使用LIMIT关键字
SELECT temp.`studentid` AS 学生编号, temp.`studentname` AS 学生姓名, temp.`studentgender` AS 学生性别, temp.`studentage` AS 学生年龄
FROM
(
    SELECT
        *,
        (SELECT COUNT(*) FROM studentinfo AS s2 WHERE s2.studentid <= s1.`studentid`) AS rownum
    FROM studentinfo AS s1
) AS temp
WHERE temp.rownum BETWEEN 4 AND 6;
时间: 2024-10-14 11:22:36

mysql<六>的相关文章

记一次MySQL找回用户数据

事情经过 有天,我们公司外区的一个销售C说他8月3号以前的工作流记录找不到了.问清缘由,原来是更新了微信号(我们公司的工作流是基于企业微信开发的).经过分析,微信号和流程数据并没什么关系,所以初步得出结论:本来只需要更新微信号的,结果我们公司的流程系统管理员把用户先删除,再创建了新的用户. 解决过程 1.首先想到的是直接从定时备份数据里面找回原来的用户ID,结果发现系统只备份了十天的记录,而工作流系统上显示销售C只有8月3号以后的流程记录,距今已经40多天,从自动备份的数据里已经无法恢复. 2.

centos7下使用yum安装mysql

CentOS7的yum源中默认好像是没有mysql的.为了解决这个问题,我们要先下载mysql的repo源. 1. 下载mysql的repo源 $ wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm 2. 安装mysql-community-release-el7-5.noarch.rpm包 $ sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm 安装这个

EF+mvc+mysql

这个真是一个大坑啊.TM折腾了一下午终于弄好了.赶紧记录下来分享给大家,免得有和我一样一直配置不成功的又折腾半天-.1.安装MySQL for Visual Studio这个直接在mysql官网下载并安装就好了.不过这个必须是vs2013 professional版本以上才可以!!2.安装MySQL Connector/Net这个可以可以通过NuGet工具获得,比较轻松愉快,当然你也可以自己下载,自己引用.3.配置web.config.首先是connectionStrings节点 1 <conn

Linux环境下MySQL数据库用SQL语句插入中文显示 “问号或者乱码 ” 问题解决!

问题: 在普通用户权限下执行 mysql -u root -p进入mysql数据库,中间步骤省略,插入数据:insert into 库名(属性)values('汉字'); 会出现如下提示:  Query OK, 1 row affected, 1 warning (0.00 sec)    表明出现错误,没有插入成功,然后执行select * from 表名   就会出现如下的问题:显示的表中出现乱码或者问号. 如图: 解决方案: 首先重新打开一个终端窗口(方便操作),进入root用户模式 执行

Centos6.5 zabbix3.2.6监控mysql

  一.     操作环境 我使用的linux系统是centos6.5,数据库是mysql5.6,apache2.4,php5,6 安装目录: /usr/local/apache /usr/local/php /usr/local/mysql /usr/local/zabbix Zabbix服务器插件安装 Zabbix3.2.6自带监控mysql模板监控项不全面,所以重新下载导入到zabbix里面 下载网址:. https://www.percona.com/downloads/percona-

MySQL数据库基础知识

day02 MySQL数据库基础知识 一.基础知识概述: 基础决定你这门课程的学习成败!只有学习好这些基础知识以后,你才能真正的运用自如.才能够对数据库有更深入的了解,道路才会越走越远. 二.基础知识: 1.数据库(database):数据库就好比是一个物理的文档柜,一个容器,把我们整理好的数据表等等归纳起来. 创建数据库命令:        create database 数据库名; 2.查看数据库         show databases; 3.打开指定的数据库         use 

MariaDB(MySQL)创建、删除、选择及数据类型使用详解

一.MariaDB简介(MySQL简介略过) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品.在存储引擎方面,使用XtraDB(英语:XtraDB)来代替MySQL的InnoDB. MariaDB由MySQL的创始人Michael Widenius(英语:Michael Widenius)主导开发,他早前曾以10亿美元的价格,将自己创建的公司MySQL A

Mac配置Mysql遇到的 --secure-file-priv问题

1.安装mysql 在官网上安装,一步步无障碍安装(但根据后来文件入法导入/导出的经验,最好在安装前设置secure-file-priv为empty,5.7.6之后似乎就默认为NULL,而secure-file-prive为NULL的话,就不支持文件导入/出) 2.安装navicat premimum 在网上找到一个破解版,按照破解步骤来安装,很好用 3.遇到的问题:在将选择的记录导出到.csv文件时,出现提示"The MySQL server is running with the --sec

MySQL(九)之数据表的查询详解(SELECT语法)二

上一篇讲了比较简单的单表查询以及MySQL的组函数,这一篇给大家分享一点比较难得知识了,关于多表查询,子查询,左连接,外连接等等.希望大家能都得到帮助! 在开始之前因为要多表查询,所以搭建好环境: 1)创建数据表suppliers 前面已经有一张表是book表,我们在建立一张suppliers(供应商)表和前面的book表对应. 也就是说 让book中s_id字段值指向suppliers的主键值,创建一个外键约束关系. 其实这里并没有达到真正的外键约束关系,只是模拟,让fruits中的s_id中

MySQL 警告WARN: Establishing SSL connection without server&#39;s identity verification is not recommended.解决办法

Success loading Mysql Driver!Mon Apr 04 15:43:00 CST 2016 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by d