mysql总结 by 刘彬

2020年4月6日加入数据蛙,第一部分内容是mysql,虽然SQL是我最熟悉的工具,但是怀着把技能学扎实的想法,按耐下心中的急躁,2天时间撸完了这部分的学习,还是有不少收获的,补充了除查询外的各种操作语句和概念知识,学会了新的技巧——变量在排序上的应用,对得起自己的认真对待
接下来的python基础的学习,结合SQL这部分的经验,python部分我将尝试直接从练习题入手,遇到不熟悉的知识再补视频,节约时间争取1天结束这部分的巩固

mysql总结

1 mysql介绍

1.1RDBS

1.2MYSQL

1.2.1数据类型

1.2.2约束

1.2.3数据库设计

1.3SQL

2 mysql使用

2.1数据库操作

-- 一、mysql 数据库的操作
    -- 连接数据库
    mysql -uroot -p密码
    
    -- 不显示密码
    mysql -uroot -p
    输入密码

    -- 退出数据库
    quit/exit

    -- sql语句最后需要有分号;结尾
    -- 显示数据库版本 version
    select version();

    -- 显示时间
    select now();
    
    -- 查看当前使用的数据库
    select database();

    -- 查看所有数据库
    show databases;

    -- 创建数据库
    -- create database 数据库名 charset=utf8;
    create database test_01;
    create database test_01 charset=utf8;

    -- 查看创建数据库的语句
    -- show create database ....
   show create database test_01;

    -- 使用数据库
    -- use 数据库的名字
    use test_01;

    -- 删除数据库
    -- drop database 数据库名;
   drop database test_01;


-- 二、数据表的操作

    -- 查看当前数据库中所有表
   show tables;
    
    -- 创建表
      -- int unsigned 无符号整形
      -- auto_increment 表示自动增长
      -- not null 表示不能为空
      -- primary key 表示主键
      -- default 默认值
      -- create table 数据表名字 (字段 类型 约束[, 字段 类型 约束]);
    create table xxx (
        id int unsigned primary key auto_increment not null,
        name varchar(20) not null
    );

    -- 查看表结构
    -- desc 数据表的名字;
    desc xxx;
   
    -- 创建 classes 表(id、name)
    create table classes (
        id int unsigned primary key not null auto_increment,
        name varchar(20) not null
    );
    
    -- 创建 students 表(id、name、age、high (decimal)、gender (enum)、cls_id)
    create table students (
        id int unsigned primary key not null auto_increment,
        name varchar(20) not null,
        age int unsigned,
        high decimal(5,2),
        gender enum("男","女","中性","保密") default "保密",
        cls_id int unsigned
    );

    -- 查看表的创建语句
    -- show create table 表名字;
   show create table xxx;

    --表字段的操作

    -- 修改表-添加字段 mascot (吉祥物)
    -- alter table 表名 add 列名 类型;
   alter table classes add chongwu varchar(20) default "一辆宝马车";

    -- 修改表-修改字段:不重命名版
    -- alter table 表名 modify 列名 类型及约束;
    alter table classes modify chongwu varchar(20) default "一栋房子";


    -- 修改表-修改字段:重命名版
    -- alter table 表名 change 原名 新名 类型及约束;
    alter table classes change chongwu mascot varchar(20) default "一个美梦";

    -- 修改表-删除字段
    -- alter table 表名 drop 列名;
    alter table classes drop mascot;

    -- 删除表
    -- drop table 表名;
    -- drop database 数据库;
   drop table xxx;
   drop database xxx;

-- 三、数据的操作,增删改查(curd)

    -- 增加
        -- 全列插入
        -- insert [into] 表名 values(...)
        -- 主键字段 可以用 0  null   default 来占位
        -- 向classes表中插入 一个班级
        insert into classes values(1,'zhansan');

        -- 向students表插入 一个学生信息,auto_increment 如果需要默认自增,可以填0,null,default
        insert into students values(1,'list',18,178,'男',001);
        insert into students values(default,'wangwu',17,170,'男',001);
        insert into students values(default,'zhaoqi',19,160,2,002);
        insert into students values(default,'zhaoba',120,160,default,003);
       

        -- 部分插入
        -- insert into 表名(列1,...) values(值1,...)
        insert into students(name) values('老李');

        -- 多行插入
        insert into students values(0,'老刘',40,160,'男',003),(0,'老王',20,180,default,003);


    -- 修改
    -- update 表名 set 列1=值1,列2=值2... where 条件;
        -- 全部修改
        update students set gender='中性';
        
        -- 按条件修改
        update students set gender='女' where id=2;
        
        -- 按条件修改多个值
        update students set gender='男' where cls_id=3;
        
    
    -- 查询基本使用
        -- 查询所有列
        -- select * from 表名;
        select * from students;

        ---定条件查询
        select * from students where cls_id=1;
        


        -- 查询指定列
        -- select 列1,列2,... from 表名;
        select name,gender from students where cls_id=1;
        


        -- 可以使用as为列或表指定别名
        -- select 字段[as 别名] , 字段[as 别名] from 数据表 where ....;
        select name as '姓名',gender as '性别' from students;


        -- 字段的顺序
        select gender as '性别',name as '姓名' from students;
        
    -- 删除
        -- 物理删除
        -- delete from 表名 where 条件
        delete from students where id=1;


        -- 逻辑删除
        -- 用一个字段来表示 这条信息是否已经不能再使用了
        -- 给students表添加一个 is_delete 字段 bit 类型
        alter table students add is_delete bit default 0;
        update students set is_delete=1 where id=3;
        
        
    
    -- 数据库备份与恢复 
        -- mysqldump –uroot –p 数据库名 > python.sql;
        -- mysql -uroot –p 新数据库名 < python.sql;

2.2查询

连接

子查询

函数

  • 聚合函数
  • 时间函数

分页

变量

排序

2.3索引

2.4视图

2.5事务

3 mysql练习

3.1销售记录数据练习


-- 第一步:建表
CREATE TABLE test6_orderinfo(
orderid    INT   PRIMARY KEY NOT NULL ,
userid      INT,
isPaid      VARCHAR(10),
price        FLOAT, 
# float decimal 
-- 是一个浮点型 一个是定点型 
-- 都可以设置(m,d)总长度和小数点后面的长度,如果不设置float会根据实际数据入库,decimal默认(10,0)将没有小数,
-- 在进行sum等计算是float会出现很多位小数的情况decimal不会
paidTime   VARCHAR(30)); 


CREATE TABLE test6_userinfo(
    userid   INT PRIMARY KEY,
    sex     VARCHAR(10),
    birth    DATE);


# 第二步,导入数据
-- C:\Users\liubi\Downloads\order_info_utf.csv
-- C:\Users\liubi\Downloads\user_info_utf.csv

#\要改成/才能被识别 而且地址不能有中文
LOAD DATA LOCAL INFILE 'c:/Users/liubi/Downloads/order_info_utf.csv' INTO TABLE test6_orderinfo FIELDS TERMINATED BY ','

LOAD DATA LOCAL INFILE 'c:/Users/liubi/Downloads/user_info_utf.csv' INTO TABLE test6_userinfo FIELDS TERMINATED BY ','
;
#做日期处理才能使用日期函数
UPDATE `datafrog`.`test6_orderinfo` a SET a.`paidTime` = REPLACE(a.`paidTime`,'/','-');
UPDATE `datafrog`.`test6_orderinfo` a SET a.`paidTime` = REPLACE(a.`paidTime`,'\r',''); # 后面STR_TO_DATE报错 包含换行符\r
#SELECT * FROM `datafrog`.`test6_orderinfo` a WHERE a.`paidTime` ='\r'

UPDATE `datafrog`.`test6_orderinfo` a SET a.`paidTime` = STR_TO_DATE(a.`paidTime`,'%Y-%m-%d %H:%i') WHERE a.`paidTime` <>'';


-- 统计不同月份的下单人数
SELECT LEFT(a.`paidTime`,7),COUNT(DISTINCT a.`userid`)
FROM `datafrog`.`test6_orderinfo` a
WHERE a.`isPaid` = '已支付'
GROUP BY LEFT(a.`paidTime`,7)
;
-- 统计用户3月份的回购率和复购率
#回购
SELECT w1.month,COUNT(w1.month),COUNT(w2.month),COUNT(w2.month)/COUNT(w1.month)
FROM (
    SELECT a1.`userid`,DATE_FORMAT(a1.`paidTime`,'%Y-%m-01') AS MONTH
    FROM `datafrog`.`test6_orderinfo` a1 
    WHERE a1.`isPaid` = '已支付' 
    GROUP BY a1.`userid`,DATE_FORMAT(a1.`paidTime`,'%Y-%m-01') 
) w1
LEFT JOIN ( 
    SELECT  a2.`userid`,DATE_FORMAT(a2.`paidTime`,'%Y-%m-01') AS MONTH
    FROM `datafrog`.`test6_orderinfo` a2 
    WHERE  a2.`isPaid` = '已支付'
    GROUP BY a2.`userid`,DATE_FORMAT(a2.`paidTime`,'%Y-%m-01') 
)w2 ON w1.userid = w2.userid AND w1.month = DATE_SUB(w2.month,INTERVAL 1 MONTH) 
GROUP BY w1.month
;

#复购
SELECT MONTH,COUNT(IF(w.paid_count>1,1,NULL)),COUNT(IF(w.paid_count>1,1,NULL))/COUNT(w.`userid`)
FROM (
SELECT LEFT(a.`paidTime`,7) AS MONTH ,a.`userid`,COUNT(*) paid_count
FROM `datafrog`.`test6_orderinfo` a
WHERE a.`isPaid` = '已支付'
GROUP BY LEFT(a.`paidTime`,7) ,a.`userid` 
) w
GROUP BY MONTH
;
-- 统计男女用户的消费频次是否有差异

SELECT a.`sex`,SUM(w.paid_count)/COUNT(a.`userid`),AVG(paid_count)
FROM `datafrog`.`test6_userinfo` a
INNER JOIN (
    SELECT  b.`userid`,COUNT(*) paid_count
    FROM `datafrog`.`test6_orderinfo` b 
    WHERE b.`isPaid` = '已支付'
    GROUP BY b.`userid`
)  w ON w.userid = a.`userid`
WHERE a.`sex` <> ''
GROUP BY a.`sex` 
;
-- 统计多次消费的用户,第一次和最后一次的消费间隔是多久
SELECT  b.`userid`,MAX(b.`paidTime`),MIN(b.`paidTime`),DATEDIFF(MAX(b.`paidTime`),MIN(b.`paidTime`))
FROM `datafrog`.`test6_orderinfo` b 
WHERE b.`isPaid` = '已支付'
GROUP BY b.`userid` #having MAX(b.`paidTime`)<>MIN(b.`paidTime`)

SELECT DATEDIFF('2019-01-01',NOW())
;
-- 统计不同年龄段用户的消费金额是否有差异

SELECT CASE WHEN YEAR(NOW())-YEAR(a.`birth`) < 10 THEN '[0-10)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 20 THEN '[10-20)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 30 THEN '[20-30)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 40 THEN '[30-40)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 50 THEN '[40-50)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 60 THEN '[50-60)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 70 THEN '[60-70)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 80 THEN '[70-80)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 90 THEN '[80-90)'
ELSE'[90-100)' END age,
SUM(w.price),AVG(price)
FROM `datafrog`.`test6_userinfo` a
INNER JOIN (
    SELECT  b.`userid`,SUM(b.`price`) price
    FROM `datafrog`.`test6_orderinfo` b 
    WHERE b.`isPaid` = '已支付'
    GROUP BY b.`userid`
)  w ON w.userid = a.`userid`
WHERE a.`birth` > '1900-01-01'
GROUP BY (CASE WHEN YEAR(NOW())-YEAR(a.`birth`) < 10 THEN '[0-10)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 20 THEN '[10-20)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 30 THEN '[20-30)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 40 THEN '[30-40)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 50 THEN '[40-50)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 60 THEN '[50-60)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 70 THEN '[60-70)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 80 THEN '[70-80)'
WHEN YEAR(NOW())-YEAR(a.`birth`) < 90 THEN '[80-90)'
ELSE'[90-100)' END)
;

-- 统计消费的二八法则,消费的top20%用户,贡献了多少额度


SELECT COUNT(w.userid),SUM(price)
FROM (
    SELECT  b.`userid`,SUM(b.`price`) price
    FROM `datafrog`.`test6_orderinfo` b 
    WHERE b.`isPaid` = '已支付'
    GROUP BY b.`userid`
    ORDER BY price DESC
    #limit 17130#(select count(distinct b.`userid`)* 0.2 from `datafrog`.`test6_orderinfo` b where b.`isPaid` = '已支付') 
) w

;


3.2学生成绩45题练习

# 数据准备

CREATE TABLE `datafrog`.Student(SId VARCHAR(10),Sname VARCHAR(10),Sage DATETIME,Ssex VARCHAR(10));

INSERT INTO Student VALUES('01' , '赵雷' , '1990-01-01' , '男');
INSERT INTO Student VALUES('02' , '钱电' , '1990-12-21' , '男');
INSERT INTO Student VALUES('03' , '孙风' , '1990-05-20' , '男');
INSERT INTO Student VALUES('04' , '李云' , '1990-08-06' , '男');
INSERT INTO Student VALUES('05' , '周梅' , '1991-12-01' , '女');
INSERT INTO Student VALUES('06' , '吴兰' , '1992-03-01' , '女');
INSERT INTO Student VALUES('07' , '郑竹' , '1989-07-01' , '女');
INSERT INTO Student VALUES('09' , '张三' , '2017-12-20' , '女');
INSERT INTO Student VALUES('10' , '李四' , '2017-12-25' , '女');
INSERT INTO Student VALUES('11' , '李四' , '2017-12-30' , '女');
INSERT INTO Student VALUES('12' , '赵六' , '2017-01-01' , '女');
INSERT INTO Student VALUES('13' , '孙七' , '2018-01-01' , '女');


CREATE TABLE `datafrog`.Course(CId VARCHAR(10),Cname NVARCHAR(10),TId VARCHAR(10)); 

INSERT INTO Course VALUES('01' , '语文' , '02'); 
INSERT INTO Course VALUES('02' , '数学' , '01'); 
INSERT INTO Course VALUES('03' , '英语' , '03'); 


CREATE TABLE `datafrog`.Teacher(TId VARCHAR(10),Tname VARCHAR(10)); 

INSERT INTO Teacher VALUES('01' , '张三');
INSERT INTO Teacher VALUES('02' , '李四'); 
INSERT INTO Teacher VALUES('03' , '王五');


CREATE TABLE `datafrog`.SC(SId VARCHAR(10),CId VARCHAR(10),score DECIMAL(18,1)); 

INSERT INTO SC VALUES('01' , '01' , 80); 
INSERT INTO SC VALUES('01' , '02' , 90); 
INSERT INTO SC VALUES('01' , '03' , 99); 
INSERT INTO SC VALUES('02' , '01' , 70); 
INSERT INTO SC VALUES('02' , '02' , 60); 
INSERT INTO SC VALUES('02' , '03' , 80); 
INSERT INTO SC VALUES('03' , '01' , 80); 
INSERT INTO SC VALUES('03' , '02' , 80); 
INSERT INTO SC VALUES('03' , '03' , 80); 
INSERT INTO SC VALUES('04' , '01' , 50); 
INSERT INTO SC VALUES('04' , '02' , 30); 
INSERT INTO SC VALUES('04' , '03' , 20); 
INSERT INTO SC VALUES('05' , '01' , 76); 
INSERT INTO SC VALUES('05' , '02' , 87); 
INSERT INTO SC VALUES('06' , '01' , 31); 
INSERT INTO SC VALUES('06' , '03' , 34); 
INSERT INTO SC VALUES('07' , '02' , 89); 
INSERT INTO SC VALUES('07' , '03' , 98);    


-- 练习题目https://www.jianshu.com/p/acacd6f4baf6

-- 1.查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
SELECT d.*,c.`CId`,c.`score`
FROM sc c
LEFT JOIN `student` d ON d.`SId` = c.`SId`
WHERE c.`SId` IN (
SELECT a.`SId`
FROM sc a
INNER JOIN sc b ON b.`SId` = a.`SId` AND b.`CId` = '02' AND b.`score` < a.`score`
WHERE a.`CId` = '01');
-- 1.1 查询同时存在" 01 "课程和" 02 "课程的情况
SELECT *
FROM sc a
WHERE a.`SId` IN (
        SELECT a.`SId`
        FROM sc a
        INNER JOIN sc b ON b.`SId` = a.`SId` AND b.`CId` = '02' 
        WHERE a.`CId` = '01'
)
;

-- 1.2 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null ) 1.3 查询不存在" 01 "课程但存在" 02 "课程的情况

-- 2.查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
SELECT a.*,w.avg_s
FROM `student` a
INNER JOIN (
    SELECT b.`SId`,AVG(b.`score`) avg_s
    FROM sc b 
    GROUP BY b.`SId` HAVING avg_s>= 60
) w ON w.SId =a.SId 
;
-- 3.查询在 SC 表存在成绩的学生信息
SELECT *
FROM `student` a
WHERE a.`SId` IN (SELECT DISTINCT b.`SId` FROM sc b )
;
-- 4.查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null ) 
SELECT a.`SId`,a.`Sname`,COUNT(DISTINCT b.`CId`) class,SUM(b.`score`) score
FROM `student` a
LEFT JOIN sc b ON b.`SId` = a.`SId`
GROUP BY a.`SId`

-- 4.1 查有成绩的学生信息
SELECT a.*
FROM `student` a
INNER JOIN sc b ON b.`SId` = a.`SId`
GROUP BY a.`SId`

-- 5.查询「李」姓老师的数量
SELECT COUNT(*)
FROM `student` a
WHERE a.`Sname` LIKE '李%';
-- 6.查询学过「张三」老师授课的同学的信息
SELECT d.*
FROM `teacher` a
INNER JOIN `course` b ON b.`TId` = a.`TId`
INNER JOIN sc c ON c.`CId` = b.`CId`
INNER JOIN `student` d ON d.`SId` = c.`SId`
WHERE a.`Tname` = '张三'
;
-- 7.查询没有学全所有课程的同学的信息
SELECT *
FROM `student` a
WHERE a.`SId` IN (
    SELECT b.`SId`
    FROM sc b 
    GROUP BY b.`SId` HAVING COUNT(DISTINCT b.`CId`)<3
)
;
-- 8.查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息
SELECT c.*
FROM  (
        SELECT *
        FROM sc a
        WHERE a.`SId` = '01'
) w
INNER JOIN `sc` b ON b.`CId` = w.CId AND b.`SId` <> '01'
LEFT JOIN `student` c ON c.`SId` = b.`SId`
GROUP BY c.`SId`
-- 9.查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息
SELECT c.*
FROM `student` c
WHERE c.`SId` IN  (
        SELECT b.`SId`
        FROM sc a
        LEFT JOIN  `sc` b ON b.`CId` = a.CId AND b.`SId` <> '01'
        WHERE a.`SId` = '01'
        GROUP BY b.`SId` HAVING COUNT(DISTINCT b.`CId`)=3 
) ;


-- 10.查询没学过"张三"老师讲授的任一门课程的学生姓名
SELECT c.*
FROM `student` c
WHERE c.`SId` NOT IN (
        SELECT a.`SId`
        FROM sc a
        INNER JOIN `course`  b ON b.`CId` =a.`CId`
        INNER JOIN `teacher` d ON d.`TId` = b.`TId` AND d.`Tname` = '张三'
);
-- 11.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
SELECT a.`SId`,b.`Sname`,AVG(a.`score`) avg_s
FROM sc a
INNER JOIN `student` b ON b.`SId` = a.`SId`
WHERE a.`SId` IN (
            SELECT w.`SId`
            FROM sc w
            WHERE w.`score` < 60
            GROUP BY w.`SId` HAVING COUNT(DISTINCT w.`CId`)>1
        )
GROUP BY a.`SId`
;
-- 12.检索" 01 "课程分数小于 60,按分数降序排列的学生信息
SELECT a.*,b.`score`
FROM `student` a
INNER JOIN  sc b ON b.`SId` = a.`SId` AND b.`score` <60 AND b.`CId` = '01'
ORDER BY b.`score` DESC ;
-- 13.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
SELECT a.*,w.avg_s
FROM sc a
LEFT JOIN (
    SELECT a.`SId`,AVG(a.`score`) avg_s
    FROM sc a
    GROUP BY a.`SId`
) w ON w.SId = a.SId
ORDER BY w.avg_s DESC
;
-- 14.查询各科成绩最高分、最低分和平均分: 
-- 以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率 
-- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
SELECT a.`CId`,b.Cname,MAX(a.score) max_s,MIN(a.score) min_s,AVG(a.score)avg_s,COUNT(DISTINCT a.SId)people,
    COUNT(CASE WHEN a.`score` >= 90 THEN 1 ELSE NULL END) /COUNT(DISTINCT a.SId) '优秀率',
    COUNT(CASE WHEN a.`score` >= 80 THEN 1 ELSE NULL END)/COUNT(DISTINCT a.SId) '优良率',
    COUNT(CASE WHEN a.`score` >= 70 THEN 1 ELSE NULL END)/COUNT(DISTINCT a.SId) '中等率',
    COUNT(CASE WHEN a.`score` >= 60 THEN 1 ELSE NULL END)/COUNT(DISTINCT a.SId) '及格率'
FROM `sc` a
LEFT JOIN `course` b ON b.CId = a.CId 
GROUP BY a.`CId`
ORDER BY people DESC, a.`CId` ASC


-- 15.按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺 
SELECT w.*,
    @rank:=@rank+1 AS rank
FROM sc w,(SELECT @rank:= 0) b
ORDER BY w.score DESC

-- 15.1 按各科成绩进行排序,并显示排名, Score 重复时合并名次
SELECT w.*,
    @rank:=IF(@s = w.score,@rank,@rank+1) AS rank,
    @s := w.score
FROM sc w,(SELECT @rank:= 0,@s:=0) b
ORDER BY w.score DESC
-- 16.查询学生的总成绩,并进行排名,总分重复时保留名次空缺 
SELECT w.*,
    @rank:=@rank+1 AS rank

FROM (
SELECT a.`SId`,SUM(a.`score`) total
FROM sc a
GROUP BY a.`SId`
ORDER BY total DESC
) w,(SELECT @rank:= 0) b
;

    -- 16.1 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺
        SELECT w.*,
            @rank:=IF(@s = w.total,@rank,@rank+1) AS rank,
            @s := w.total
        FROM (
        SELECT a.`SId`,SUM(a.`score`) total
        FROM sc a
        GROUP BY a.`SId`
        ORDER BY total DESC
        ) w,(SELECT @rank:= 0,@s:=0) b
        ;

-- 17.统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比
SELECT a.`CId`,
    COUNT(CASE WHEN a.`score` >= 0 AND a.`score` < 60 THEN 1 ELSE NULL END) '[60-0]人数',
    COUNT(CASE WHEN a.`score` >= 0 AND a.`score` < 60 THEN 1 ELSE NULL END) /COUNT(*) '[60-0]占比',
    COUNT(CASE WHEN a.`score` >= 60 AND a.`score` < 70 THEN 1 ELSE NULL END) '[70-60]人数',
    COUNT(CASE WHEN a.`score` >= 60 AND a.`score` < 70 THEN 1 ELSE NULL END) /COUNT(*) '[70-60]占比',
    COUNT(CASE WHEN a.`score` >= 70 AND a.`score` < 85 THEN 1 ELSE NULL END) '[85-70]人数',
    COUNT(CASE WHEN a.`score` >= 70 AND a.`score` < 85 THEN 1 ELSE NULL END) /COUNT(*) '[85-70]占比',
    COUNT(CASE WHEN a.`score` >= 85 AND a.`score` < 100 THEN 1 ELSE NULL END) '[100-85]人数',
    COUNT(CASE WHEN a.`score` >= 85 AND a.`score` < 100 THEN 1 ELSE NULL END) /COUNT(*) '[100-85]占比'
FROM `sc` a
GROUP BY a.`CId`



-- 18.查询各科成绩前三名的记录
SELECT m.*
FROM (
SELECT
    a.*,
    @rank:= IF(@c=a.CId,@rank+1,1) AS rank ,
    @c:= a.CId
FROM sc a ,(SELECT @rank:=0,@c:= NULL) b
ORDER BY a.`CId`,a.`score` DESC
) m
WHERE m.rank <= 3;

SELECT m.*
FROM (
SELECT
    a.*,
    (SELECT COUNT(DISTINCT b.score) FROM sc b WHERE b.CId = a.`CId` AND b.score >= a.`score`) AS rank

FROM sc a
ORDER BY a.`CId`,a.`score` DESC
) m
WHERE m.rank <= 3

-- 19.查询每门课程被选修的学生数
SELECT a.`CId`,COUNT(DISTINCT a.`SId`)
FROM `sc` a
GROUP BY a.`CId`;

-- 20.查询出只选修两门课程的学生学号和姓名
SELECT b.`SId`,b.`Sname`
FROM`student` b
WHERE b.`SId` IN  (
    SELECT a.`SId`
    FROM sc a
    GROUP BY a.`SId` HAVING COUNT(DISTINCT a.`CId`)=2
)
-- 21.查询男生、女生人数
SELECT a.`Ssex`,COUNT(*)
FROM `student` a
GROUP BY a.`Ssex`;
-- 22.查询名字中含有「风」字的学生信息
SELECT *
FROM `student` a
WHERE a.`Sname` LIKE '%风%';
-- 23.查询同名同性学生名单,并统计同名人数
SELECT a.`Sname`,COUNT(*)
FROM `student` a
GROUP BY a.`Sname` HAVING COUNT(*)>1;
-- 24.查询 1990 年出生的学生名单
SELECT *
FROM `student` a
WHERE YEAR(a.`Sage`) = 1990;
-- 25.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
SELECT a.`CId`,AVG(a.`score`) a_score
FROM `sc` a
GROUP BY a.`CId`
ORDER BY a_score DESC,a.CId ASC;
-- 26.查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
SELECT a.*,w.avg_s
FROM `student` a
INNER JOIN (
    SELECT b.`SId`,AVG(b.`score`) avg_s
    FROM sc b 
    GROUP BY b.`SId` HAVING avg_s>= 85
) w ON w.SId =a.SId 
;
-- 27.查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
SELECT c.`Sname`,b.`score`
FROM `course` a
INNER JOIN sc b ON b.`CId` = a.`CId` AND b.`score` <60
INNER JOIN `student` c ON c.`SId` = b.`SId`
WHERE a.`Cname` = '数学';
-- 28.查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
SELECT *
FROM `student` a
LEFT JOIN sc b ON b.`SId` = a.`SId`

-- 29.查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
SELECT a.`Sname`,d.`Cname`,b.`score`
FROM `student` a
INNER JOIN sc b ON b.`SId` = a.`SId` 
LEFT JOIN `course` d ON d.`CId` = b.`CId`
WHERE NOT EXISTS (
    SELECT *
    FROM sc c 
    WHERE c.`score` < 70 AND c.`SId` = a.`SId`
);
-- 30.查询不及格的课程
SELECT *
FROM sc c 
WHERE c.`score` < 60
;
-- 31.查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名
SELECT a.`SId`,a.`Sname`
FROM `student` a
INNER JOIN sc b ON b.`SId` = a.`SId` AND b.`CId` ='01' AND b.`score`>= 80

-- 32.求每门课程的学生人数
SELECT a.`CId`,COUNT(DISTINCT a.`SId`)
FROM `sc` a
GROUP BY a.`CId`;
-- 33.假设成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
SELECT d.*,c.`score`
FROM `teacher` a
INNER JOIN `course` b ON b.`TId` = a.`TId`
INNER JOIN sc c ON c.`CId` = b.`CId`
INNER JOIN `student` d ON d.`SId` = c.`SId`
INNER JOIN (
    SELECT MAX(c.`score`) score
    FROM `teacher` a
    INNER JOIN `course` b ON b.`TId` = a.`TId`
    INNER JOIN sc c ON c.`CId` = b.`CId`
    WHERE a.`Tname` = '张三'
) w ON w.score = c.`score`
WHERE a.`Tname` = '张三'

-- 34.假设成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

SELECT  d.*,c.`score`
FROM `teacher` a
INNER JOIN `course` b ON b.`TId` = a.`TId`
INNER JOIN sc c ON c.`CId` = b.`CId`
INNER JOIN `student` d ON d.`SId` = c.`SId`
WHERE a.`Tname` = '张三'
ORDER BY c.`score` DESC LIMIT 1

-- 35.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
SELECT *
FROM `sc` a
INNER JOIN `sc` b ON b.`score` = a.`score` AND b.`CId` <> a.`CId`
GROUP BY a.`SId`,a.`CId`,a.`score`
-- 36.查询每门功成绩最好的前两名

SELECT a.`CId`,a.`SId`,
    a.`score`,@rank := IF(@class =a.CId, @rank + 1 ,1)AS rank,
    @class := a.CId
FROM `sc` AS a 
INNER JOIN (SELECT @rank := 0, @class:=0) r
LEFT JOIN `student` s ON s.`SId` = a.`SId`
LEFT JOIN `course` c ON c.`CId` = a.`CId`
ORDER BY a.`CId`,a.`score` DESC


;
SELECT m.*,
    @rank := IF(@class =m.CId, @rank + 1 ,1)AS rank,
    @class := m.CId
FROM (

SELECT w.`CId`,c.`Cname`,w.`SId`,s.`Sname`,w.`score`
FROM `sc` w 
INNER JOIN `student` s ON s.`SId` = w.`SId`
LEFT JOIN `course` c ON c.`CId` = w.`CId`
) m ,(SELECT @rank := 0,@class:=0) r
ORDER BY m.`CId`,m.`score` DESC
;

-- 37.统计每门课程的学生选修人数(超过 5 人的课程才统计)。

SELECT b.`CId`,COUNT(DISTINCT b.`SId`)
FROM `datafrog`.sc b 
GROUP BY b.`CId` HAVING COUNT(DISTINCT b.`SId`)>5
;
-- 38.检索至少选修两门课程的学生学号

SELECT b.SId
FROM `datafrog`.sc b 
GROUP BY b.`SId` HAVING COUNT(DISTINCT b.`CId`)>=3
;
-- 39.查询选修了全部课程的学生信息
SELECT * 
FROM `datafrog`.`student` a
WHERE a.`SId` IN (
        SELECT b.SId
        FROM `datafrog`.sc b 
        GROUP BY b.`SId` HAVING COUNT(DISTINCT b.`CId`)=3)

-- 40.查询各学生的年龄,只按年份来算
SELECT a.*,YEAR(NOW())-YEAR(a.`Sage`) AS age
FROM `datafrog`.`student` a

;
-- 41.按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
SELECT a.*,TIMESTAMPDIFF(YEAR,a.`Sage`,NOW())AS age
FROM `datafrog`.`student` a


-- 42.查询本周过生日的学生
SELECT a.*,WEEK(a.`Sage`)
FROM `datafrog`.`student` a
WHERE WEEK(a.`Sage`) = WEEK(NOW())
;
-- 43.查询下周过生日的学生
SELECT *
FROM `datafrog`.`student` a
WHERE WEEK(a.`Sage`) - WEEK(NOW()) =1

-- 44.查询本月过生日的学生

SELECT *
FROM `datafrog`.`student` a
WHERE MONTH(a.`Sage`) = MONTH(NOW())
;
-- 45.查询下月过生日的学生
SELECT *
FROM `datafrog`.`student` a
WHERE MONTH(a.`Sage`) - MONTH(NOW()) = 1
;

3.3lettcode练习

  • 体育馆人流高峰期计算
CREATE TABLE `datafrog`.test (
id INT NOT NULL UNIQUE PRIMARY KEY,
visit_date DATE NOT NULL ,
people INT NOT NULL
)

INSERT INTO `datafrog`.test VALUES 
(1,'2017-01-01',10),
(2,'2017-01-02',109),
(3,'2017-01-03',150),
(4,'2017-01-04',99),
(5,'2017-01-05',145),
(6,'2017-01-06',1455),
(7,'2017-01-07',199),
(8,'2017-01-08',188)


SELECT id, visit_date, people
FROM (
    SELECT r1.*, @flag := IF((r1.countt >= 3 OR @flag = 1) AND r1.countt != 0, 1, 0) AS flag
    FROM (
        SELECT s.*, @count := IF(s.people >= 100, @count + 1, 0) AS `countt`
        SELECT *
        FROM test s, (SELECT @count := 0) b
    ) r1, (SELECT @flag := 0) c
    ORDER BY id DESC
) result
WHERE flag = 1 ORDER BY id;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容