1.函数
概念:已经设计好的程序,我们在写SQL语句时候就可以直接使用,提供SQL计算效率
分类:
1)分组函数(统计函数):sum; count; min; max; avg
2)单行函数:字符串函数;日期函数;数学函数
分组函数,它要配合group by;having查询
案例-1:查询一张里面总条数
SELECT COUNT(sNO) FROM students;
如果用count(*),则会将NULL值一起进行计算(不过滤NULL情况)
案例-2:求学生成绩总和,思考:能不能进行字符串求和,或者 NULL求和
SELECT SUM(elscore) FROM elogs; – 含有NULL值,则不参与求和
SELECT SUM(sName) FROM students; – 字符串求和,结果为0
案例-3:求分数最低和最高
SELECT MIN(elscore), MAX(elscore) FROM elogs;
如果将NULL值进行计算,则不参数计算
案例-4:求男生和女生的考试平均分(先分组,然后完成平均值)
– 先完成连接查询,把想要数据先进性筛选
Select sID, elScore, sSex from elogs a, students b where s.sID = b.sNO;
– 去掉ID的字段,然后对elScore做求平均计算
SELECT AVG(elScore),sSex FROM elogs a, students b WHERE a.sID = b.sNo GROUP BY sSex;
案例-5:求每位学生考试的平均分
– 不含有未参加考试
SELECT sName, AVG(elScore) FROM elogs, students WHERE sNO = sID GROUP BY sNO;
– 包含所有学生成绩(包括挂科的)
SELECT sName, IFNULL(AVG(elScore),0) FROM students LEFT OUTER JOIN elogs ON sNO = sID GROUP BY sNO;
案例-6:完成如下的数据查询
科目 100-90 90-80 80-70 70-60 60以下
语文 2人 5人 3人 6人 3人
数学 3人 3人 5人 7人 2人
外语 5人 2人 6人 3人 3人
1)Case…when 条件判断查询(关键字case, when ,then, end)
– 第一种case…when的用法
SELECT
SYSDATE(),
CASE WEEKDAY(SYSDATE())
WHEN 0 THEN ‘星期一’
WHEN 1 THEN ‘星期二’
WHEN 2 THEN ‘星期三’
WHEN 3 THEN ‘星期四’
WHEN 4 THEN ‘星期五’
WHEN 5 THEN ‘星期六’
WHEN 6 THEN ‘星期天’
END 星期
– 第二种 case when的用法
SELECT
SYSDATE(),
CASE
WHEN WEEKDAY(SYSDATE()) = 0 THEN ‘星期一’
WHEN WEEKDAY(SYSDATE()) = 1 THEN ‘星期二’
WHEN WEEKDAY(SYSDATE()) = 2 THEN ‘星期三’
WHEN WEEKDAY(SYSDATE()) = 3 THEN ‘星期四’
WHEN WEEKDAY(SYSDATE()) = 4 THEN ‘星期五’
WHEN WEEKDAY(SYSDATE()) = 5 THEN ‘星期六’
WHEN WEEKDAY(SYSDATE()) = 6 THEN ‘星期天’
END 星期
2)SQL代码
– 先查询你要的数据
SELECT cName, elScore FROM courses, elogs WHERE cID = cNo
– 对数据进行筛选
SELECT cName,
SUM(CASE WHEN elScore >= 90 AND elScore <= 100 THEN 1 ELSE 0 END) ‘100-90’,
SUM(CASE WHEN elScore >= 80 AND elScore < 90 THEN 1 ELSE 0 END) ‘90-80’,
SUM(CASE WHEN elScore >= 70 AND elScore < 80 THEN 1 ELSE 0 END) ‘80-70’,
SUM(CASE WHEN elScore >= 60 AND elScore < 70 THEN 1 ELSE 0 END) ‘70-60’,
SUM(CASE WHEN elScore < 60 THEN 1 ELSE 0 END) ‘60以下’
FROM courses, elogs WHERE cID = cNo GROUP BY cNO
2.作业:完成一个复杂的查询
科目 总人数 男生 女生 平均分 最高分 最低分
语文 5人 3人 2人 89.9 90 89
数学 3人 1人 2人 90 90 90
外语 2人 1人 1人 88 90 88.5
3.作业:设计一个数据库模型,完成表与表之间关系(简书网站的数据库设计)
4.字符串函数
SELECT CONCAT(‘Hello’, ‘World’)
SELECT LOWER(‘HelloWorld’), UPPER(‘HelloWorld’)
SELECT LTRIM(’ HelloWorld’), RTRIM('HelloWorld ‘), TRIM(’ HelloWorld ')
SELECT LPAD(‘H’, 3, ‘’), RPAD(‘H’, 3, '’)
SELECT REPLACE(‘HelloWorld’, ‘World’, ‘***’)
SELECT SUBSTRING(‘HelloWorld’, 3, 3)
SELECT LENGTH(‘天府五街’),CHARACTER_LENGTH(‘天府五街’), CHARACTER_LENGTH(‘HelloWorld’)
5.日期函数
SELECT NOW(), CURDATE(), CURTIME()
SELECT WEEK(NOW()), YEAR(NOW()), WEEKDAY(NOW())
SELECT DATE_FORMAT(NOW(), ‘%Y年%m月%d日 %H小时%i分%s秒’)
SELECT DATEDIFF(NOW(), ‘2019-07-22’)
SELECT WEEKDAY(STR_TO_DATE(‘2019-07-22 23:23:23’, ‘%Y-%m-%d %H:%i:%s’))
SELECT DATE_ADD(NOW(), INTERVAL 2 HOUR)
案例-1:查询出生日期是在1998年的同学
SELECT * FROM students WHERE sAge = TRUNCATE(DATEDIFF(NOW(), ‘1998-01-01’) / 365, 0)
SELECT * FROM students WHERE sAge = YEAR(NOW()) - 1998
案例-2:查询姓名是三个字的同学
SELECT * FROM students WHERE CHARACTER_LENGTH(sName) = 3
SELECT * FROM students WHERE sName LIKE ‘___’
案例-3:把身份证的中间5位数字隐藏掉,换成*号
SELECT REPLACE(sCard, SUBSTRING(sCard, 5, 5), ‘*****’) FROM students;
案例-4:统计1998年的男生和女生的人数
SELECT sSex, COUNT(sNo) FROM students WHERE sAge = YEAR(NOW()) - 1998 GROUP BY sSex;
案例-5:统计1998年每个月份出生的男生和女生人数
性别 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
男生 1人 0人 2人 3人 1人 0人 2人 3人 1人 0人 1人 0人
女生 2人 3人 3人 1人 3人 1人 3人 1人 0人 2人 3人 1人
SELECT sSex,
SUM(CASE WHEN SUBSTRING(sCard, 11, 2) = 01 THEN 1 ELSE 0 END) ‘1月’,
SUM(CASE WHEN SUBSTRING(sCard, 11, 2) = 02 THEN 1 ELSE 0 END) ‘2月’,
SUM(CASE WHEN SUBSTRING(sCard, 11, 2) = 03 THEN 1 ELSE 0 END) ‘3月’,
SUM(CASE WHEN SUBSTRING(sCard, 11, 2) = 04 THEN 1 ELSE 0 END) ‘4月’,
SUM(CASE WHEN SUBSTRING(sCard, 11, 2) = 05 THEN 1 ELSE 0 END) ‘5月’,
SUM(CASE WHEN SUBSTRING(sCard, 11, 2) = 06 THEN 1 ELSE 0 END) ‘6月’,
SUM(CASE WHEN SUBSTRING(sCard, 11, 2) = 07 THEN 1 ELSE 0 END) ‘7月’,
SUM(CASE WHEN SUBSTRING(sCard, 11, 2) = 08 THEN 1 ELSE 0 END) ‘8月’,
SUM(CASE WHEN SUBSTRING(sCard, 11, 2) = 09 THEN 1 ELSE 0 END) ‘9月’,
SUM(CASE WHEN SUBSTRING(sCard, 11, 2) = 10 THEN 1 ELSE 0 END) ‘10月’,
SUM(CASE WHEN SUBSTRING(sCard, 11, 2) = 11 THEN 1 ELSE 0 END) ‘11月’,
SUM(CASE WHEN SUBSTRING(sCard, 11, 2) = 12 THEN 1 ELSE 0 END) ‘12月’
FROM students
WHERE SUBSTRING(sCard, 7, 4) = 1990
GROUP BY sSex;
6.子查询
概念:在一个select语句里面包含一个select,则这种情况就是一个子查询
子查询出现位置
1)在一个where条件后面跟一个select
2)from关键字后面跟select子查询
3)in关键字里面跟select子查询
4)Any关键字里面跟select子查询
5)All关键字里面跟select子查询
6)exists关键字里面跟select子查询
案例-1:找出年龄小于平均年龄的同学
– 分组函数不能在where关键字后面做比较
SELECT * FROM students WHERE sAge < (SELECT AVG(sAge) FROM students)
案例-2:查询日期在9月,10月,11月的同学
SELECT * FROM students WHERE SUBSTRING(sCard, 11, 2) IN (09, 10, 11)
案例-3:删除表里面重复数据,保留其中一条数据
1)能不能得到表行号(子查询,在from关键字里子查询)
2)保留其中对应最小的行号
3)删除整个表,然后完成一个insert插入
SELECT (@rownum:=0) – 设置一个变量,在SQL查询里面设置变量
SELECT (@rownum:=@rownum+1) rownum, id, NAME FROM temp,(SELECT (@rownum:=0)) b
SELECT MIN(c.rownum), c.id, c.name FROM (SELECT (@rownum:=@rownum+1) rownum, id, NAME FROM temp,(SELECT (@rownum:=0)) b) c GROUP BY c.id
CREATE TABLE tt (SELECT MIN(c.rownum), c.id, c.name FROM (SELECT (@rownum:=@rownum+1) rownum, id, NAME FROM temp,(SELECT (@rownum:=0)) b) c GROUP BY c.id)
DELETE FROM temp;
INSERT INTO temp SELECT id, NAME FROM tt
7.数据库设计
工具:PowerDesigner,转换数据库脚本
概念:表与表之间的关系(一对一,一对多,多对多)
案例:简书网数据库设计
1)表名:数据库_表名
2)列名:表名_字段名
3)每个表都必须有主键
---------------------------基础查询练习-----------------------------------------------------------------
表如下:
相关练习如下:
1、为所有学生的密码进行重置(000000)
update students set sPassword='000000'
2、新的一年到了,所有教师的年龄都要调整
update teachers set tAge=tAge+1;
3、将没有安排授课老师,且课程学分不为0 的课程的学分改为0
update courses set cCredit=0 where tID is null and cCredit!=0
4、将选修登记时间在2018年10月20日之前的数据进行删除
delete from elogs where elDate<'2018-10-20'
5、课程《Visual FoxPro》不准备再开设,请将其从课程信息表中删除
delete from courses where cName='Visual FoxPro'
6、学号为20182101的同学因违反校规而被开除,请依次将其在学生信息及选修记录信息表中的数据进行删除
delete from students,elogs where elogs.sID=students.sNo and students.sNo='20182101'
7、因为课程《计算机应用基础》考试后发现试题泄露,现对该课程所有学生的成绩改为0分,以便重新考试登分
update elogs set elScore=0 where elogs.cID=(select cNo from courses where cName='计算机应用基础'
8、增加教师信息(编号:0010,姓名:z's,性别:男,年龄:30)
insert into teachers(tNo,tName,tGender,tAge) values ('0010','z\'s','男',30);
9、统计学生信息表(Students)中没有填写手机号码的同学有多少人
select count(1) from students where sMobile is null
10、查看教师信息表(Teachers)中年龄不小于25岁的老师姓名及性别
-- select tName,tGender from teachers where tAge>=25;
-- 11、根据课程信息表结构,添加一条自定义数据的记录
insert into courses values('00005','c++程序设计','0001',5,null)
-- 12、在选修记录信息表(eLogs)中,根据学生选修时间排序,将最近登记的五条记录返回
-- select * from elogs order by elDate limit 5
-- 13、在课程信息表(Courses)中,将学分分别为3,4,5的课程名称返回
-- select cName from courses where cNo in (3,4,5)
-- 14、在课程信息表(Courses)中,删除课程描述为空的课程信息
-- delete from courses where cDescription is null
-- 15、将课程信息表(Courses)中课程描述字段的长度改为200
-- alter table courses modify cDescription char(200)
-- 16、在选修记录信息表(eLogs)中,更新学号为20180101,选修课程编号为00002的考试成绩为80
-- update elogs set elScore=80 where sID='20180101' and cID='00002'
-- 17、在教师信息表(Teachers)中,返回年龄范围在24至35的老师名称及编号
-- select tName,tNo from teachers where tAge between 24 and 35
-- 18、在课程信息表(Courses)中,查询课程名称中出现了“语言”的课程信息
-- select * from courses where cDescription like '%语言%'
-- 19、在选修记录信息表(eLogs)中,统计学生所选课程门数(同编号课程只统计一次)
-- select COUNT(DISTINCT cID) from elogs;
-- 20、统计《计算机网络基础》这门课程有多少学生考试及格(一门课程同一个学生只能选择一次)
-- select count(1) from elogs where elScore>=60 and cID=(select cNo from courses where cName='计算机网络基础')
-- select count(1) from elogs,courses where elScore>=60 and elogs.cID=courses.cNo AND courses.cName='计算机网络基础'
-- 21、统计《计算机网络基础》这门课程缺考的同学有多少
-- 22、查询张峰老师所授的每门课程名称
-- select cName from courses,teachers where courses.tID=teachers.tNo and teachers.tName='张峰'
-- select cName from courses where tID=(select tNo from teachers where tName='张峰')
-- 23、查询哪门课程选修登记的学生人数最多
-- select cID,COUNT(cID) from elogs group by cID ORDER BY COUNT(cID) desc limit 1;
-- 24、统计不同性别老师的平均年龄及人数,输出效果如下图所示
-- select tGender,avg(tAge),count(1) from teachers group by tGender
-- 25、查询哪些学生未进行选修学习
-- select sNo from students where sNo not in (select sID from elogs)
-- 26、统计选修学分达到十分及以上的同学有哪些 ??????????????????????????????
-- select sName from students where sNo=(select sID from elogs where SUM(elScore)>10 group by sNo);
-- 27、查询在2018年里姓王的同学选修考试成绩最高的分数是多少
-- select max(elScore) from elogs,students where elogs.sID=students.sNo AND students.sName like '王%' and year(elogs.elDate)=2018
-- 28、统计教师不同姓氏的人数分别有多少??????????????????????????????????
-- 29、查看课程描述中包含“计算机”或“电脑”字眼的课程名称及其编号
-- select cNo,cName from courses where cDescription like '%计算机%' or cDescription like '%电脑%'
-- 30、统计《C语言》这门课程选修成绩中最高成绩与最低成绩的分值差
-- 31、查看王军老师所授课程的考试成绩属于良的同学有哪些(考试成绩在75与85之间,但不包含85为良)
/*select sName
from
students
where sNo in (select sID from elogs where elScore>=75 and elScore<85 and cID in (select cNo from courses where tID=(select tNo from teachers where tName='王军')))*/
/*select sName
from students,teachers,elogs,courses
where (elogs.cID=courses.cNo)
and (courses.tID=teachers.tNo)
and (elogs.sID=students.sNo)
and (teachers.tName='王军')
and (elogs.elScore>=75 and elogs.elScore<85)
*/