目录
一、基础查询
二、过滤和排序数据
三、Order by子句
四、排序案例
五、拓展案例
一、基础查询
1、语法:select? 查询列表??from 表名
2、特点:
2.1、查询列表可以是:表中的字段、常量值、表达式、函数
2.2、查询的结果是一个虚拟的表格
3、实例:
3.1.查询表中的单个字段
?
SELECT last_name FROM t_mysql_employees;
?
3.2.查询表中的多个字段
SELECT last_name,salary,email FROM t_mysql_employees;
?
3.3.查询表中的所有字段
?
方式一:
SELECT
`employee_id`,
`first_name`,
`last_name`,
`phone_number`,
`last_name`,
`job_id`,
`phone_number`,
`job_id`,
`salary`,
`commission_pct`,
`manager_id`,
`department_id`,
`hiredate`
FROM
t_mysql_employees ;
方式二:
SELECT * FROM t_mysql_employees;
3.4.查询常量值
SELECT 100;
SELECT 'john';
3.5.查询表达式
SELECT 100%98;
3.6.查询函数
SELECT VERSION();
3.7:起别名:
目的:①便于理解 ? ? ? ? ? ?②如果要查询的字段有重名的情况,使用别名可以区分开来
3.8:去重:把表格中重复的字段去掉
SELECT DISTINCT department_id FROM t_mysql_employees;
3.9:+号的作用:说起加号,就要和JAVA中的加号进行对比了。 ? ? ? ? ? ? java中的+号: ? ? ? ? ? ? ? ? ? ? ①运算符,两个操作数都为数值型 ? ? ? ? ? ? ? ? ? ? ②连接符,只要有一个操作数为字符串 ? ? ? ? ?? mysql中的+号:仅仅只有一个功能:运算符。
3.9.1+号的几种情况:
? ? 1、两个操作数都为数值型,则做加法运算
2、只要其中一方为字符型,试图将字符型数值转换成数值型,如果转换成功,则继续做加法运算
3、如果转换失败,则将字符型数值转换成0?
?4、只要其中一方为null,则结果肯定为null
二、过滤和排序数据
1、过滤 2、在查询中过滤行 3、where子句 4、比较运算 5、between 6、in 7、like 8、null 9、逻辑运算
语法:
select
查询列表
from
表名
where
筛选条件;
?
分类:
一、按条件表达式筛选
简单条件运算符:> < = != <> >= <=
二、按逻辑表达式筛选
逻辑运算符:
作用:用于连接条件表达式
&& || !
and or not
&&和and:两个条件都为true,结果为true,反之为false
||或or: 只要有一个条件为true,结果为true,反之为false
!或not: 如果连接的条件本身为false,结果为true,反之为false
三、模糊查询
like
between and
in
is null
*/
#一、按条件表达式筛选
?
#案例1:查询工资>12000的员工信息
?
SELECT
*
FROM
t_mysql_employees
WHERE
salary>12000;
#案例2:查询部门编号不等于90号的员工名和部门编号
SELECT
last_name,
department_id
FROM
t_mysql_employees
WHERE
department_id<>90;
?
?
#二、按逻辑表达式筛选
?
#案例1:查询工资z在10000到20000之间的员工名、工资以及奖金
SELECT
last_name,
salary,
commission_pct
FROM
t_mysql_employees
WHERE
salary>=10000 AND salary<=20000;
#案例2:查询部门编号不是在90到110之间,或者工资高于15000的员工信息
SELECT
*
FROM
t_mysql_employees
WHERE
NOT(department_id>=90 AND department_id<=110) OR salary>15000;
#三、模糊查询
/*
like
?
between and
in
is null|is not null
?
*/
#1.like
/*
特点:
①一般和通配符搭配使用
通配符:
% 任意多个字符,包含0个字符
_ 任意单个字符
*、
?
#案例1:查询员工名中包含字符a的员工信息
?
select
*
from
employees
where
last_name like '%a%';#abc
#案例2:查询员工名中第三个字符为e,第五个字符为a的员工名和工资
select
last_name,
salary
FROM
t_mysql_employees
WHERE
last_name LIKE '__n_l%';
?
?
?
案例3:查询员工名中第二个字符为_的员工名
?
SELECT
last_name
FROM
t_mysql_employees
WHERE
last_name LIKE '_$_%' ESCAPE '$';
2.between and
/*
①使用between and 可以提高语句的简洁度
②包含临界值
③两个临界值不要调换顺序
?
*/
?
?
#案例1:查询员工编号在100到120之间的员工信息
?
SELECT
*
FROM
t_mysql_employees
WHERE
employee_id <= 120 AND employee_id>=100;
#----------------------
SELECT
*
FROM
t_mysql_employees
WHERE
employee_id BETWEEN 100 AND 120;
?
?
#3.in
/*
含义:判断某字段的值是否属于in列表中的某一项
特点:
①使用in提高语句简洁度
②in列表的值类型必须一致或兼容
③in列表中不支持通配符
?
*/
#案例:查询员工的工种编号是 IT_PROG、AD_VP、AD_PRES中的一个员工名和工种编号
?
SELECT
last_name,
job_id
FROM
t_mysql_employees
WHERE
job_id = 'IT_PROT' OR job_id = 'AD_VP' OR JOB_ID ='AD_PRES';
?
?
#------------------
?
SELECT
last_name,
job_id
FROM
t_mysql_employees
WHERE
job_id IN( 'IT_PROT' ,'AD_VP','AD_PRES');
?
#4、is null
/*
=或<>不能用于判断null值
is null或is not null 可以判断null值
?
?
?
?
*/
?
#案例1:查询没有奖金的员工名和奖金率
SELECT
last_name,
commission_pct
FROM
t_mysql_employees
WHERE
commission_pct IS NULL;
?
?
#案例1:查询有奖金的员工名和奖金率
SELECT
last_name,
commission_pct
FROM
t_mysql_employees
WHERE
commission_pct IS NOT NULL;
?
#----------以下为×
SELECT
last_name,
commission_pct
FROM
t_mysql_employees
?
WHERE
salary IS 12000;
#安全等于 <=>
?
?
#案例1:查询没有奖金的员工名和奖金率
SELECT
last_name,
commission_pct
FROM
t_mysql_employees
WHERE
commission_pct <=>NULL;
#案例2:查询工资为12000的员工信息
SELECT
last_name,
salary
FROM
t_mysql_employees
?
WHERE
salary <=> 12000;
?
#is null pk <=>
?
IS NULL:仅仅可以判断NULL值,可读性较高,建议使用
<=> :既可以判断NULL值,又可以判断普通的数值,可读性较低
三、Order by子句
?1、按单个字段排序
案例:按员工表薪资排序
?SELECT * FROM t_mysql_employees ORDER BY salary DESC;
2、添加筛选条件再排序
案例:查询部门编号>=90的员工信息,并按员工编号降序
?SELECT * FROM t_mysql_employees WHERE department_id>=90 ORDER BY employee_id DESC;
3、按表达式排序
案例:查询员工信息 按年薪降序
??SELECT *,salary*12*(1+IFNULL(commission_pct,0)) FROM t_mysql_employees ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC;
4、按别名排序
案例:查询员工信息 按年薪升序
????SELECT *,salary*12*(1+IFNULL(commission_pct,0)) 年薪 FROM t_mysql_employees
5、按函数排序
案例:查询员工名,并且按名字的长度降序
SELECT LENGTH(last_name),last_name FROM t_mysql_employees ORDER BY LENGTH(last_name) DESC;
6、按多个字段排序
?案例:查询员工信息,要求先按工资降序,再按employee_id升序
SELECT * FROM t_mysql_employees ORDER BY salary DESC,employee_id ASC;
四、排序案例
1.查询员工的姓名和部门号和年薪,按年薪降序 按姓名升序
select last_name,department_id,salary*12*(1+IFNULL(commission_pct,0)) from t_mysql_employees ORDER BY salary*12*(1+IFNULL(commission_pct,0)) desc,last_name asc
2.选择工资不在8000到17000的员工的姓名和工资,按工资降序
SELECT last_name,salary from t_mysql_employees ORDER BY salary*12*(1+IFNULL(commission_pct,0)) desc,salary not in(8000,17000)
3.查询邮箱中包含e的员工信息,并先按邮箱的字节数降序,再按部门号升序
SELECT * from t_mysql_employees where email like '%e%' ORDER BY LENGTH(email) desc ,department_id asc
五、拓展案例
1、首先建立四个表并且分别插入数据
-- 1.学生表-t_student
-- sid 学生编号,sname 学生姓名,sage 学生年龄,ssex 学生性别
CREATE TABLE t_student(
sid VARCHAR(20),
sname VARCHAR(20),
sage date,
ssex VARCHAR(20)
)
-- 2.教师表-t_teacher
-- tid 教师编号,tname 教师名称
create table t_teacher(
tid VARCHAR(20),
tname VARCHAR(20)
)
-- 3.课程表-t_course
-- cid 课程编号,cname 课程名称,tid 教师名称
create table t_course(
cid VARCHAR(20),
cname VARCHAR(20),
tid VARCHAR(20)
)
-- 4.成绩表-t_score
-- sid 学生编号,cid 课程编号,score 成绩
CREATE table t_score(
sid VARCHAR(20),
cid VARCHAR(20),
score INT
)
-- 学生表
insert into t_student values('01' , '赵雷' , '1990-01-01' , '男');
insert into t_student values('02' , '钱电' , '1990-12-21' , '男');
insert into t_student values('03' , '孙风' , '1990-12-20' , '男');
insert into t_student values('04' , '李云' , '1990-12-06' , '男');
insert into t_student values('05' , '周梅' , '1991-12-01' , '女');
insert into t_student values('06' , '吴兰' , '1992-01-01' , '女');
insert into t_student values('07' , '郑竹' , '1989-01-01' , '女');
insert into t_student values('09' , '张三' , '2017-12-20' , '女');
insert into t_student values('10' , '李四' , '2017-12-25' , '女');
insert into t_student values('11' , '李四' , '2012-06-06' , '女');
insert into t_student values('12' , '赵六' , '2013-06-13' , '女');
insert into t_student values('13' , '孙七' , '2014-06-01' , '女');
-- 教师表
insert into t_teacher values('01' , '张三');
insert into t_teacher values('02' , '李四');
insert into t_teacher values('03' , '王五');
-- 成绩表
insert into t_score values('01' , '01' , 80);
insert into t_score values('01' , '02' , 90);
insert into t_score values('01' , '03' , 99);
insert into t_score values('02' , '01' , 70);
insert into t_score values('02' , '02' , 60);
insert into t_score values('02' , '03' , 80);
insert into t_score values('03' , '01' , 80);
insert into t_score values('03' , '02' , 80);
insert into t_score values('03' , '03' , 80);
insert into t_score values('04' , '01' , 50);
insert into t_score values('04' , '02' , 30);
insert into t_score values('04' , '03' , 20);
insert into t_score values('05' , '01' , 76);
insert into t_score values('05' , '02' , 87);
insert into t_score values('06' , '01' , 31);
insert into t_score values('06' , '03' , 34);
insert into t_score values('07' , '02' , 89);
insert into t_score values('07' , '03' , 98);
-- 课程表
insert into t_course values('01' , '语文' , '02');
insert into t_course values('02' , '数学' , '01');
insert into t_course values('03' , '英语' , '03');
select * from t_course
select * from t_score
select * from t_teacher
select * from t_student
2、案例(大部分都是使用内连接的)
01)查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
SELECT a.*,b.score 01score,c.score 02score
FROM t_student as a
INNER JOIN t_score as b
ON a.sid = b.sid
INNER JOIN t_score as c
ON a.sid = c.sid and b.cid = '01' and c.cid = '02'
where b.score > c.score;
解题思路:
1、首先将成绩表分为‘01’和‘02’两部分,'01'数据视为b表,'02'数据视为c表
通过cid将两个表连接起来,然后再筛选出" 01 "课程比" 02 "课程成绩高的
2、将学生表t_student看做为a表,分别用sid将a表与b表和c表相关联,并且查询出
学生的信息及课程分数
02)查询同时存在" 01 "课程和" 02 "课程的情况
SELECT * FROM
(SELECT * FROM t_score WHERE cId = '01') AS a
INNER JOIN (SELECT * FROM t_score WHERE cId = '02') AS b
ON a.sId = b.sId;
解题思路:首先将查询条件结果为cid=‘01’看做a表,再将查询结果为cid=‘02’的看做b表,并且用sid将这连个表连接起来
03)查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )
SELECT * from
(SELECT * from t_score where cid ='01') as a
LEFT JOIN t_score AS b
ON a.sId = b.sId AND b.cId = '02';
解题思路:首先将查询结果为cid='01'的看做是a表,再将成绩表看作是b表,用sid将这两个表连接起来,同时添加一个b表中cid=‘02’的条件,代表着可能的意思
04)查询不存在" 01 "课程但存在" 02 "课程的情况
select * from t_score where sid not in (
SELECT sid FROM t_score WHERE cId = '01'
)and cid = '02'
解题思路:
查询条件1:先查询出cid为'01'的sid,同时赋予条件cid=‘02’
查询条件2:其次再查询所有不为查询条件1的学生信息
05)查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
SELECT a.sid,a.sname,b.c from
t_student as a
INNER JOIN (SELECT sid,AVG(score) AS c
FROM t_score
GROUP BY sid
HAVING AVG(score) >= 60) AS b
ON a.sid = b.sid;
解题思路:1、首先将学生编号进行分组,再过滤出平均数大于60的学生编号
同时将平均分取名为c,整个查询条件取名为b表
? ? ? ? ? ? ? ? ? ? ? ?2、将学生表看做是a表,用sid将a,b表连接,在查询学生编号和学生姓名和平均成绩
? 06)查询在t_score表存在成绩的学生信息?
SELECT b.* from
(SELECT sid from t_score GROUP BY sid) a
LEFT JOIN t_student b
on a.sid=b.sid
? 解题思路:先将存在分数的学生编号在成绩表里进行分组,然后再将这部分学生编号与学生表里的学生编号进行比较
07)查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为null )
SELECT a.sid,a.sname,b.zs,b.zcj
FROM t_student AS a
LEFT JOIN (SELECT sid,COUNT(cid) AS zs,SUM(score) AS zcj
FROM t_score
GROUP BY sid) AS b
ON a.sid = b.sid;
?解题思路:先将总数与总成绩拿出来,将学生编号进行分组,然后将a表与b表用sid相连接,在查询条件就可以了
08)查询「李」姓老师的数量 ?
select count(*) from t_teacher where tname like '李%'
解题思路:用like '李%'进行模糊查询出姓李的老师,然后再用Count(*)统计数量
09)查询学过「张三」老师授课的同学的信息
select * from t_student where sid in (
select sid from t_score where cid =(
select cid from t_course where tid =(
select tid from t_teacher where tname ='张三'
)
)
)
解题思路:1、先查询出老师姓名为张三的老师编号
? ? ? ? ? ? ? ? ? 2、再查询出张三老师的课程编号
? ? ? ? ? ? ? ? ? ?3、再通过该编号拿到对应课程的学生编号
? ? ? ? ? ? ? ? ? ?4、再通过学生编号拿到所有的学生信息
10)查询没有学全所有课程的同学的信息 ?
SELECT a.*,kc
FROM t_student AS a
INNER JOIN (SELECT sid,COUNT(cid) AS kc
? ? ? ? ? ? FROM t_score
? ? ? ? ? ? GROUP BY sid
? ? ? ? ? ? HAVING kc < (SELECT COUNT(cid) FROM t_course)) AS b
ON a.sid = b.sid;
?解题思路:1、先拿到学生的选修情况取别名为kc然后将学生编号进行分组
? ? ? ? ? ? ? ? ? 2、再过滤筛选出没有学全的学生编号看做为b表
? ? ? ? ? ? ? ?3、将学生表看做a表用sid与b表相连接
11)查询没学过"张三"老师讲授的任一门课程的学生姓名
SELECT sname
FROM t_student AS a
WHERE sid NOT IN (SELECT sid
FROM t_score AS a
LEFT JOIN t_course AS b
ON a.cid = b.cid
INNER JOIN t_teacher AS c
ON b.tid = c.tid
WHERE tname = '张三');
解题思路:
??????????????????1、先查询出老师姓名为张三的老师编号
? ? ? ? ? ? ? ? ? 2、再查询出张三老师的课程编号
? ? ? ? ? ? ? ? ? ?3、再通过该编号拿到对应课程的学生编号
? ? ? ? ? ? ? ? ? ?4、在加条件not?in?就是不存在的意思来拿到不在该条件下的学生编号,通过该编号就能拿到没有选修张三老师课程的学生姓名
12)查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
SELECT c.sid,d.sname,pjf
FROM(SELECT a.sid,AVG(score) AS pjf
FROM t_score AS a
INNER JOIN(SELECT sid
FROM t_score
WHERE score < 60
GROUP BY sid
HAVING COUNT(cid) >= 2) AS b
ON a.sid = b.sid
GROUP BY a.sid) AS c
LEFT JOIN t_student AS d
ON c.sid = d.sid;
解题思路:
13)检索" 01 "课程分数小于 60,按分数降序排列的学生信息
SELECT b.*,a.score
FROM(SELECT sid,score
? ? ?FROM t_score
? ? ?WHERE cid = '01' AND score < 60) AS a
LEFT JOIN t_student AS b
ON a.sid = b.sid
ORDER BY a.score desc;
14)按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
SELECT a.sid,a.cid,a.score,pjcj
FROM(SELECT a.sid,b.cid,b.score
? ? ?FROM t_student AS a
? ? ?LEFT JOIN t_score AS b
? ? ?ON a.sid = b.sid) AS a
LEFT JOIN (SELECT sid,AVG(score) AS pjcj
? ? ? ? ? ?FROM t_score
? ? ? ? ? ?GROUP BY sid) AS b
ON a.sid = b.sid
ORDER BY b.pjcj DESC;
解题思路:
15)查询各科成绩最高分、最低分和平均分: 以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
SELECT a.*,b.Cname
FROM(SELECT?
? ? ?cid,
? ? ?COUNT(*) ? AS 选修人数,
? ? ?MAX(score) AS 最高分,
? ? ?MIN(score) AS 最低分,
? ? ?AVG(score) AS 平均分,
? ? ?SUM(CASE WHEN score >= 60 THEN 1 ELSE 0 END) / COUNT(*) AS 及格率,
? ? ?SUM(CASE WHEN score >= 70 AND score < 80 THEN 1 ELSE 0 END) / COUNT(*) AS 中等率,
? ? ?SUM(CASE WHEN score >= 80 AND score < 90 THEN 1 ELSE 0 END) / COUNT(*) AS 优良率,
? ? ?SUM(CASE WHEN score >= 90 THEN 1 ELSE 0 END) / COUNT(*) AS 优秀率
? ? ?FROM t_score
? ? ?GROUP BY cid
? ? ?ORDER BY COUNT(*) DESC,CId ASC) AS a
LEFT JOIN t_course AS b
ON a.cid = b.cid;
解题思路:
|