Mysql核心(二)——数据查询
一、语法
select 查询列表 from 表名;
二、特点
1、查询列表可以是字段、常量、表达式、函数,也可以是多个
2、查询结果是一个虚拟表
三、示例
1、查询单个字段
select 字段名 from 表名;
2、查询多个字段
select 字段名,字段名 from 表名;
3、查询所有字段
select * from 表名
4、查询常量
select 常量值;
注意:字符型和日期型的常量值必须用单引号引起来,数值型不需要
5、查询函数
select 函数名(实参列表);
6、查询表达式
select 100/1234;
7、起别名
①as
②空格
8、去重
select distinct 字段名 from 表名;
9、+
作用:做加法运算
select 数值+数值; 直接运算
select 字符+数值;先试图将字符转换成数值,如果转换成功,则继续运算;否则转换成0,再做运算
select null+值;结果都为null
10、【补充】concat函数
功能:拼接字符
select concat(字符1,字符2,字符3,...);
11、【补充】ifnull函数
功能:判断某字段或表达式是否为null,如果为null 返回指定的值,否则返回原本的值
select ifnull(commission_pct,0) from employees;
12、【补充】isnull函数
功能:判断某字段或表达式是否为null,如果是,则返回1,否则返回0
1 /* 2 语法: 3 select 查询列表 from 表名; 4 5 类似于:System.out.println(打印东西); 6 特点: 7 1、查询列表可以是:表中的字段、常量值、表达式、函数 8 2、查询的结果是一个虚拟的表格 9 */ 10 USE myemployees; 11 #1.查询表中的单个字段 12 SELECT last_name FROM employees; 13 #2.查询表中的多个字段 14 SELECT last_name,salary,email FROM employees; 15 #3.查询表中的所有字段 16 #方式一: 17 SELECT 18 `employee_id`, 19 `first_name`, 20 `last_name`, 21 `phone_number`, 22 `last_name`, 23 `job_id`, 24 `phone_number`, 25 `job_id`, 26 `salary`, 27 `commission_pct`, 28 `manager_id`, 29 `department_id`, 30 `hiredate` 31 FROM 32 employees ; 33 #方式二: 34 SELECT * FROM employees; 35 #4.查询常量值 36 SELECT 100; 37 SELECT 'john'; 38 #5.查询表达式 39 SELECT 100%98; 40 #6.查询函数 41 SELECT VERSION(); 42 #7.起别名 43 /* 44 ①便于理解 45 ②如果要查询的字段有重名的情况,使用别名可以区分开来 46 */ 47 #方式一:使用as 48 SELECT 100%98 AS 结果; 49 SELECT last_name AS 姓,first_name AS 名 FROM employees; 50 #方式二:使用空格 51 SELECT last_name 姓,first_name 名 FROM employees; 52 53 #案例:查询salary,显示结果为 out put 54 SELECT salary AS "out put" FROM employees; 55 56 #8.去重 57 58 #案例:查询员工表中涉及到的所有的部门编号 59 SELECT DISTINCT department_id FROM employees; 60 61 #9.+号的作用 62 /* 63 java中的+号: 64 ①运算符,两个操作数都为数值型 65 ②连接符,只要有一个操作数为字符串 66 mysql中的+号: 67 仅仅只有一个功能:运算符 68 select 100+90; 两个操作数都为数值型,则做加法运算 69 select '123'+90;只要其中一方为字符型,试图将字符型数值转换成数值型 70 如果转换成功,则继续做加法运算 71 select 'john'+90; 如果转换失败,则将字符型数值转换成0 72 select null+10; 只要其中一方为null,则结果肯定为null 73 */ 74 #案例:查询员工名和姓连接成一个字段,并显示为 姓名 75 76 SELECT CONCAT('a','b','c') AS 结果; 77 SELECT 78 CONCAT(last_name,first_name) AS 姓名 79 FROM 80 employees;
查询总结
语法:
select 查询列表 ⑦
from 表1 别名 ①
连接类型 join 表2 ②
on 连接条件 ③
where 筛选 ④
group by 分组列表 ⑤
having 筛选 ⑥
order by排序列表 ⑧
limit 起始条目索引,条目数; ⑨
二、条件查询
一、语法
select 查询列表
from 表名
where 筛选条件
二、筛选条件的分类
1、简单条件运算符
> < = <> != >= <= <=>安全等于
2、逻辑运算符
&& and
|| or
! not
3、模糊查询
like:一般搭配通配符使用,可以判断字符型或数值型
通配符:%任意多个字符,_任意单个字符
between and
in
is null /is not null:用于判断null值
is null PK <=>
普通类型的数值 null值 可读性
is null × √ √
<=> √ √ ×
1 /* 2 语法: 3 select 4 查询列表 5 from 6 表名 7 where 8 筛选条件; 9 分类: 10 一、按条件表达式筛选 11 12 简单条件运算符:> < = != <> >= <= 13 14 二、按逻辑表达式筛选 15 逻辑运算符: 16 作用:用于连接条件表达式 17 && || ! 18 and or not 19 20 &&和and:两个条件都为true,结果为true,反之为false 21 ||或or: 只要有一个条件为true,结果为true,反之为false 22 !或not: 如果连接的条件本身为false,结果为true,反之为false 23 24 三、模糊查询 25 like 26 between and 27 in 28 is null 29 30 */ 31 #一、按条件表达式筛选 32 #案例1:查询工资>12000的员工信息 33 SELECT 34 * 35 FROM 36 employees 37 WHERE 38 salary>12000; 39 40 41 #案例2:查询部门编号不等于90号的员工名和部门编号 42 SELECT 43 last_name, 44 department_id 45 FROM 46 employees 47 WHERE 48 department_id<>90; 49 50 #二、按逻辑表达式筛选 51 #案例1:查询工资z在10000到20000之间的员工名、工资以及奖金 52 SELECT 53 last_name, 54 salary, 55 commission_pct 56 FROM 57 employees 58 WHERE 59 salary>=10000 AND salary<=20000; 60 #案例2:查询部门编号不是在90到110之间,或者工资高于15000的员工信息 61 SELECT 62 * 63 FROM 64 employees 65 WHERE 66 NOT(department_id>=90 AND department_id<=110) OR salary>15000; 67 #三、模糊查询 68 /* 69 like 70 71 72 between and 73 in 74 is null|is not null 75 */ 76 #1.like 77 /* 78 特点: 79 ①一般和通配符搭配使用 80 通配符: 81 % 任意多个字符,包含0个字符 82 _ 任意单个字符 83 *、 84 #案例1:查询员工名中包含字符a的员工信息 85 select 86 * 87 from 88 employees 89 where 90 last_name like '%a%';#abc 91 #案例2:查询员工名中第三个字符为e,第五个字符为a的员工名和工资 92 select 93 last_name, 94 salary 95 FROM 96 employees 97 WHERE 98 last_name LIKE '__n_l%'; 99 100 101 #案例3:查询员工名中第二个字符为_的员工名 102 SELECT 103 last_name 104 FROM 105 employees 106 WHERE 107 last_name LIKE '_$_%' ESCAPE '$'; 108 #2.between and 109 /* 110 ①使用between and 可以提高语句的简洁度 111 ②包含临界值 112 ③两个临界值不要调换顺序 113 */ 114 115 #案例1:查询员工编号在100到120之间的员工信息 116 SELECT 117 * 118 FROM 119 employees 120 WHERE 121 employee_id >= 120 AND employee_id<=100; 122 #---------------------- 123 SELECT 124 * 125 FROM 126 employees 127 WHERE 128 employee_id BETWEEN 120 AND 100; 129 #3.in 130 /* 131 含义:判断某字段的值是否属于in列表中的某一项 132 特点: 133 ①使用in提高语句简洁度 134 ②in列表的值类型必须一致或兼容 135 ③in列表中不支持通配符 136 137 */ 138 #案例:查询员工的工种编号是 IT_PROG、AD_VP、AD_PRES中的一个员工名和工种编号 139 SELECT 140 last_name, 141 job_id 142 FROM 143 employees 144 WHERE 145 job_id = 'IT_PROT' OR job_id = 'AD_VP' OR JOB_ID ='AD_PRES'; 146 147 #------------------ 148 SELECT 149 last_name, 150 job_id 151 FROM 152 employees 153 WHERE 154 job_id IN( 'IT_PROT' ,'AD_VP','AD_PRES'); 155 #4、is null 156 /* 157 =或<>不能用于判断null值 158 is null或is not null 可以判断null值 159 160 161 162 */ 163 #案例1:查询没有奖金的员工名和奖金率 164 SELECT 165 last_name, 166 commission_pct 167 FROM 168 employees 169 WHERE 170 commission_pct IS NULL; 171 172 #案例1:查询有奖金的员工名和奖金率 173 SELECT 174 last_name, 175 commission_pct 176 FROM 177 employees 178 WHERE 179 commission_pct IS NOT NULL; 180 #----------以下为× 181 SELECT 182 last_name, 183 commission_pct 184 FROM 185 employees 186 WHERE 187 salary IS 12000; 188 189 190 #安全等于 <=> 191 192 #案例1:查询没有奖金的员工名和奖金率 193 SELECT 194 last_name, 195 commission_pct 196 FROM 197 employees 198 WHERE 199 commission_pct <=>NULL; 200 201 202 #案例2:查询工资为12000的员工信息 203 SELECT 204 last_name, 205 salary 206 FROM 207 employees 208 WHERE 209 salary <=> 12000; 210 211 #is null pk <=> 212 IS NULL:仅仅可以判断NULL值,可读性较高,建议使用 213 <=> :既可以判断NULL值,又可以判断普通的数值,可读性较低
三、排序查询
一、语法
select 查询列表
from 表
where 筛选条件
order by 排序列表 【asc}desc】
二、特点
1、asc :升序,如果不写默认升序
desc:降序
2、排序列表 支持 单个字段、多个字段、函数、表达式、别名
3、order by的位置一般放在查询语句的最后(除limit语句之外)
1 /* 2 语法: 3 select 查询列表 4 from 表名 5 【where 筛选条件】 6 order by 排序的字段或表达式; 7 8 特点: 9 1、asc代表的是升序,可以省略 10 desc代表的是降序 11 2、order by子句可以支持 单个字段、别名、表达式、函数、多个字段 12 3、order by子句在查询语句的最后面,除了limit子句 13 */ 14 #1、按单个字段排序 15 SELECT * FROM employees ORDER BY salary DESC; 16 #2、添加筛选条件再排序 17 #案例:查询部门编号>=90的员工信息,并按员工编号降序 18 SELECT * 19 FROM employees 20 WHERE department_id>=90 21 ORDER BY employee_id DESC; 22 23 #3、按表达式排序 24 #案例:查询员工信息 按年薪降序 25 26 SELECT *,salary*12*(1+IFNULL(commission_pct,0)) 27 FROM employees 28 ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC; 29 30 #4、按别名排序 31 #案例:查询员工信息 按年薪升序 32 SELECT *,salary*12*(1+IFNULL(commission_pct,0)) 年薪 33 FROM employees 34 ORDER BY 年薪 ASC; 35 #5、按函数排序 36 #案例:查询员工名,并且按名字的长度降序 37 SELECT LENGTH(last_name),last_name 38 FROM employees 39 ORDER BY LENGTH(last_name) DESC; 40 #6、按多个字段排序 41 #案例:查询员工信息,要求先按工资降序,再按employee_id升序 42 SELECT * 43 FROM employees 44 ORDER BY salary DESC,employee_id ASC;
案例讲解
1 #1.查询员工的姓名和部门号和年薪,按年薪降序 按姓名升序 2 SELECT last_name,department_id,salary*12*(1+IFNULL(commission_pct,0)) 年薪 3 FROM employees 4 ORDER BY 年薪 DESC,last_name ASC; 5 6 #2.选择工资不在8000到17000的员工的姓名和工资,按工资降序 7 SELECT last_name,salary 8 FROM employees 9 WHERE salary NOT BETWEEN 8000 AND 17000 10 ORDER BY salary DESC; 11 #3.查询邮箱中包含e的员工信息,并先按邮箱的字节数降序,再按部门号升序 12 SELECT *,LENGTH(email) 13 FROM employees 14 WHERE email LIKE '%e%' 15 ORDER BY LENGTH(email) DESC,department_id ASC;
四、常见函数
一、概述
功能:类似于java中的方法
好处:提高重用性和隐藏实现细节
调用:select 函数名(实参列表);
二、单行函数
1、字符函数
concat:连接
substr:截取子串
upper:变大写
lower:变小写
replace:替换
length:获取字节长度
trim:去前后空格
lpad:左填充
rpad:右填充
instr:获取子串第一次出现的索引
2、数学函数
ceil:向上取整
round:四舍五入
mod:取模
floor:向下取整
truncate:截断
rand:获取随机数,返回0-1之间的小数
3、日期函数
now:返回当前日期+时间
year:返回年
month:返回月
day:返回日
date_format:将日期转换成字符
curdate:返回当前日期
str_to_date:将字符转换成日期
curtime:返回当前时间
hour:小时
minute:分钟
second:秒
datediff:返回两个日期相差的天数
monthname:以英文形式返回月
4、其他函数
version 当前数据库服务器的版本
database 当前打开的数据库
user当前用户
password('字符'):返回该字符的密码形式
md5('字符'):返回该字符的md5加密形式
5、流程控制函数
①if(条件表达式,表达式1,表达式2):如果条件表达式成立,返回表达式1,否则返回表达式2
②case情况1
case 变量或表达式或字段
when 常量1 then 值1
when 常量2 then 值2
...
else 值n
end
③case情况2
case
when 条件1 then 值1
when 条件2 then 值2
...
else 值n
end
三、分组函数
1、分类
max 最大值
min 最小值
sum 和
avg 平均值
count 计算个数
2、特点
①语法
select max(字段) from 表名;
②支持的类型
sum和avg一般用于处理数值型
max、min、count可以处理任何数据类型
③以上分组函数都忽略null
④都可以搭配distinct使用,实现去重的统计
select sum(distinct 字段) from 表;
⑤count函数
count(字段):统计该字段非空值的个数
count(*):统计结果集的行数
案例:查询每个部门的员工个数
1 xx 10
2 dd 20
3 mm 20
4 aa 40
5 hh 40
count(1):统计结果集的行数
效率上:
MyISAM存储引擎,count(*)最高
InnoDB存储引擎,count(*)和count(1)效率>count(字段)
⑥ 和分组函数一同查询的字段,要求是group by后出现的字段
1 /* 2 概念:类似于java的方法,将一组逻辑语句封装在方法体中,对外暴露方法名 3 好处:1、隐藏了实现细节 2、提高代码的重用性 4 调用:select 函数名(实参列表) 【from 表】; 5 特点: 6 ①叫什么(函数名) 7 ②干什么(函数功能) 8 分类: 9 1、单行函数 10 如 concat、length、ifnull等 11 2、分组函数 12 13 功能:做统计使用,又称为统计函数、聚合函数、组函数 14 15 常见函数: 16 一、单行函数 17 字符函数: 18 length:获取字节个数(utf-8一个汉字代表3个字节,gbk为2个字节) 19 concat 20 substr 截取字符串 21 instr 获取某一个字符在大字符串中的索引 22 trim 23 upper 24 lower 25 lpad 26 rpad 27 replace 28 29 数学函数: 30 round 31 ceil 32 floor 33 truncate 34 mod 35 36 日期函数: 37 now 38 curdate 39 curtime 40 year 41 month 42 monthname 43 day 44 hour 45 minute 46 second 47 str_to_date 48 date_format 49 其他函数: 50 version 51 database 52 user 53 控制函数 54 if 55 case 56 57 58 */ 59 60 #一、字符函数 61 #1.length 获取参数值的字节个数 62 SELECT LENGTH('john'); 63 SELECT LENGTH('张三丰hahaha'); 64 SHOW VARIABLES LIKE '%char%' 65 #2.concat 拼接字符串 66 SELECT CONCAT(last_name,'_',first_name) 姓名 FROM employees; 67 #3.upper、lower 68 SELECT UPPER('john'); 69 SELECT LOWER('joHn'); 70 #示例:将姓变大写,名变小写,然后拼接 71 SELECT CONCAT(UPPER(last_name),LOWER(first_name)) 姓名 FROM employees; 72 #4.substr、substring 73 注意:索引从1开始 74 #截取从指定索引处后面所有字符 75 SELECT SUBSTR('李莫愁爱上了陆展元',7) out_put; 76 #截取从指定索引处指定字符长度的字符 77 SELECT SUBSTR('李莫愁爱上了陆展元',1,3) out_put; 78 79 #案例:姓名中首字符大写,其他字符小写然后用_拼接,显示出来 80 SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),'_',LOWER(SUBSTR(last_name,2))) out_put 81 FROM employees; 82 #5.instr 返回子串第一次出现的索引,如果找不到返回0 83 SELECT INSTR('杨不殷六侠悔爱上了殷六侠','殷八侠') AS out_put; 84 #6.trim 85 SELECT LENGTH(TRIM(' 张翠山 ')) AS out_put; 86 SELECT TRIM('aa' FROM 'aaaaaaaaa张aaaaaaaaaaaa翠山aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') AS out_put; 87 #7.lpad 用指定的字符实现左填充指定长度 88 SELECT LPAD('殷素素',2,'*') AS out_put; 89 #8.rpad 用指定的字符实现右填充指定长度 90 SELECT RPAD('殷素素',12,'ab') AS out_put; 91 92 #9.replace 替换 93 SELECT REPLACE('周芷若周芷若周芷若周芷若张无忌爱上了周芷若','周芷若','赵敏') AS out_put; 94 95 96 #二、数学函数 97 #round 四舍五入 98 SELECT ROUND(-1.55); 99 SELECT ROUND(1.567,2); 100 101 #ceil 向上取整,返回>=该参数的最小整数 102 SELECT CEIL(-1.02); 103 #floor 向下取整,返回<=该参数的最大整数 104 SELECT FLOOR(-9.99); 105 #truncate 截断 106 SELECT TRUNCATE(1.69999,1); 107 #mod取余 108 /* 109 mod(a,b) : a-a/b*b 110 mod(-10,-3):-10- (-10)/(-3)*(-3)=-1 111 */ 112 SELECT MOD(10,-3); 113 SELECT 10%3; 114 115 #三、日期函数 116 #now 返回当前系统日期+时间 117 SELECT NOW(); 118 #curdate 返回当前系统日期,不包含时间 119 SELECT CURDATE(); 120 #curtime 返回当前时间,不包含日期 121 SELECT CURTIME(); 122 123 #可以获取指定的部分,年、月、日、小时、分钟、秒 124 SELECT YEAR(NOW()) 年; 125 SELECT YEAR('1998-1-1') 年; 126 SELECT YEAR(hiredate) 年 FROM employees; 127 SELECT MONTH(NOW()) 月; 128 SELECT MONTHNAME(NOW()) 月; 129 130 #str_to_date 将字符通过指定的格式转换成日期 131 SELECT STR_TO_DATE('1998-3-2','%Y-%c-%d') AS out_put; 132 #查询入职日期为1992--4-3的员工信息 133 SELECT * FROM employees WHERE hiredate = '1992-4-3'; 134 SELECT * FROM employees WHERE hiredate = STR_TO_DATE('4-3 1992','%c-%d %Y'); 135 136 #date_format 将日期转换成字符 137 SELECT DATE_FORMAT(NOW(),'%y年%m月%d日') AS out_put; 138 #查询有奖金的员工名和入职日期(xx月/xx日 xx年) 139 SELECT last_name,DATE_FORMAT(hiredate,'%m月/%d日 %y年') 入职日期 140 FROM employees 141 WHERE commission_pct IS NOT NULL; 142 143 #四、其他函数 144 SELECT VERSION(); 145 SELECT DATABASE(); 146 SELECT USER(); 147 148 #五、流程控制函数 149 #1.if函数: if else 的效果 150 SELECT IF(10<5,'大','小'); 151 SELECT last_name,commission_pct,IF(commission_pct IS NULL,'没奖金,呵呵','有奖金,嘻嘻') 备注 152 FROM employees; 153 154 155 156 #2.case函数的使用一: switch case 的效果 157 /* 158 java中 159 switch(变量或表达式){ 160 case 常量1:语句1;break; 161 ... 162 default:语句n;break; 163 164 } 165 mysql中 166 case 要判断的字段或表达式 167 when 常量1 then 要显示的值1或语句1; 168 when 常量2 then 要显示的值2或语句2; 169 ... 170 else 要显示的值n或语句n; 171 end 172 */ 173 /*案例:查询员工的工资,要求 174 部门号=30,显示的工资为1.1倍 175 部门号=40,显示的工资为1.2倍 176 部门号=50,显示的工资为1.3倍 177 其他部门,显示的工资为原工资 178 */ 179 180 SELECT salary 原始工资,department_id, 181 CASE department_id 182 WHEN 30 THEN salary*1.1 183 WHEN 40 THEN salary*1.2 184 WHEN 50 THEN salary*1.3 185 ELSE salary 186 END AS 新工资 187 FROM employees; 188 189 190 #3.case 函数的使用二:类似于 多重if 191 /* 192 java中: 193 if(条件1){ 194 语句1; 195 }else if(条件2){ 196 语句2; 197 } 198 ... 199 else{ 200 语句n; 201 } 202 mysql中: 203 case 204 when 条件1 then 要显示的值1或语句1 205 when 条件2 then 要显示的值2或语句2 206 。。。 207 else 要显示的值n或语句n 208 end 209 */ 210 #案例:查询员工的工资的情况 211 如果工资>20000,显示A级别 212 如果工资>15000,显示B级别 213 如果工资>10000,显示C级别 214 否则,显示D级别 215 216 SELECT salary, 217 CASE 218 WHEN salary>20000 THEN 'A' 219 WHEN salary>15000 THEN 'B' 220 WHEN salary>10000 THEN 'C' 221 ELSE 'D' 222 END AS 工资级别 223 FROM employees;
【案例讲解】单行函数
1 #1. 显示系统时间(注:日期+时间) 2 SELECT NOW(); 3 #2. 查询员工号,姓名,工资,以及工资提高百分之20%后的结果(new salary) 4 SELECT employee_id,last_name,salary,salary*1.2 "new salary" 5 FROM employees; 6 #3. 将员工的姓名按首字母排序,并写出姓名的长度(length) 7 SELECT LENGTH(last_name) 长度,SUBSTR(last_name,1,1) 首字符,last_name 8 FROM employees 9 ORDER BY 首字符; 10 11 #4. 做一个查询,产生下面的结果 12 <last_name> earns <salary> monthly but wants <salary*3> 13 Dream Salary 14 King earns 24000 monthly but wants 72000 15 16 SELECT CONCAT(last_name,' earns ',salary,' monthly but wants ',salary*3) AS "Dream Salary" 17 FROM employees 18 WHERE salary=24000; 19 20 #5. 使用case-when,按照下面的条件: 21 job grade 22 AD_PRES A 23 ST_MAN B 24 IT_PROG C 25 SA_REP D 26 ST_CLERK E 27 产生下面的结果 28 Last_name Job_id Grade 29 king AD_PRES A 30 31 SELECT last_name,job_id AS job, 32 CASE job_id 33 WHEN 'AD_PRES' THEN 'A' 34 WHEN 'ST_MAN' THEN 'B' 35 WHEN 'IT_PROG' THEN 'C' 36 WHEN 'SA_PRE' THEN 'D' 37 WHEN 'ST_CLERK' THEN 'E' 38 END AS Grade 39 FROM employees 40 WHERE job_id = 'AD_PRES';
【练习讲解】分组函数
1 #1.查询公司员工工资的最大值,最小值,平均值,总和 2 SELECT MAX(salary) 最大值,MIN(salary) 最小值,AVG(salary) 平均值,SUM(salary) 和 3 FROM employees; 4 #2.查询员工表中的最大入职时间和最小入职时间的相差天数 (DIFFRENCE) 5 SELECT MAX(hiredate) 最大,MIN(hiredate) 最小,(MAX(hiredate)-MIN(hiredate))/1000/3600/24 DIFFRENCE 6 FROM employees; 7 SELECT DATEDIFF(MAX(hiredate),MIN(hiredate)) DIFFRENCE 8 FROM employees; 9 SELECT DATEDIFF('1995-2-7','1995-2-6'); 10 11 #3.查询部门编号为90的员工个数 12 SELECT COUNT(*) FROM employees WHERE department_id = 90;
分级函数
1 /* 2 功能:用作统计使用,又称为聚合函数或统计函数或组函数 3 分类: 4 sum 求和、avg 平均值、max 最大值 、min 最小值 、count 计算个数 5 特点: 6 1、sum、avg一般用于处理数值型 7 max、min、count可以处理任何类型 8 2、以上分组函数都忽略null值 9 3、可以和distinct搭配实现去重的运算 10 4、count函数的单独介绍 11 一般使用count(*)用作统计行数 12 5、和分组函数一同查询的字段要求是group by后的字段 13 */ 14 15 #1、简单 的使用 16 SELECT SUM(salary) FROM employees; 17 SELECT AVG(salary) FROM employees; 18 SELECT MIN(salary) FROM employees; 19 SELECT MAX(salary) FROM employees; 20 SELECT COUNT(salary) FROM employees; 21 22 SELECT SUM(salary) 和,AVG(salary) 平均,MAX(salary) 最高,MIN(salary) 最低,COUNT(salary) 个数 23 FROM employees; 24 SELECT SUM(salary) 和,ROUND(AVG(salary),2) 平均,MAX(salary) 最高,MIN(salary) 最低,COUNT(salary) 个数 25 FROM employees; 26 #2、参数支持哪些类型 27 SELECT SUM(last_name) ,AVG(last_name) FROM employees; 28 SELECT SUM(hiredate) ,AVG(hiredate) FROM employees; 29 SELECT MAX(last_name),MIN(last_name) FROM employees; 30 SELECT MAX(hiredate),MIN(hiredate) FROM employees; 31 SELECT COUNT(commission_pct) FROM employees; 32 SELECT COUNT(last_name) FROM employees; 33 #3、是否忽略null 34 SELECT SUM(commission_pct) ,AVG(commission_pct),SUM(commission_pct)/35,SUM(commission_pct)/107 FROM employees; 35 SELECT MAX(commission_pct) ,MIN(commission_pct) FROM employees; 36 SELECT COUNT(commission_pct) FROM employees; 37 SELECT commission_pct FROM employees; 38 39 #4、和distinct搭配 40 SELECT SUM(DISTINCT salary),SUM(salary) FROM employees; 41 SELECT COUNT(DISTINCT salary),COUNT(salary) FROM employees; 42 43 #5、count函数的详细介绍 44 SELECT COUNT(salary) FROM employees; 45 46 SELECT COUNT(*) FROM employees; 47 SELECT COUNT(1) FROM employees; 48 效率: 49 MYISAM存储引擎下 ,COUNT(*)的效率高 50 INNODB存储引擎下,COUNT(*)和COUNT(1)的效率差不多,比COUNT(字段)要高一些 51 52 #6、和分组函数一同查询的字段有限制 53 SELECT AVG(salary),employee_id FROM employees;
五、分组查询
1 /* 2 语法: 3 select 查询列表 4 from 表 5 【where 筛选条件】 6 group by 分组的字段 7 【order by 排序的字段】; 8 特点: 9 1、和分组函数一同查询的字段必须是group by后出现的字段 10 2、筛选分为两类:分组前筛选和分组后筛选 11 针对的表 位置 连接的关键字 12 分组前筛选 原始表 group by前 where 13 14 分组后筛选 group by后的结果集 group by后 having 15 问题1:分组函数做筛选能不能放在where后面 16 答:不能 17 问题2:where——group by——having 18 一般来讲,能用分组前筛选的,尽量使用分组前筛选,提高效率 19 3、分组可以按单个字段也可以按多个字段 20 4、可以搭配着排序使用 21 */ 22 23 24 #引入:查询每个部门的员工个数 25 SELECT COUNT(*) FROM employees WHERE department_id=90; 26 #1.简单的分组 27 #案例1:查询每个工种的员工平均工资 28 SELECT AVG(salary),job_id 29 FROM employees 30 GROUP BY job_id; 31 #案例2:查询每个位置的部门个数 32 SELECT COUNT(*),location_id 33 FROM departments 34 GROUP BY location_id; 35 36 #2、可以实现分组前的筛选 37 #案例1:查询邮箱中包含a字符的 每个部门的最高工资 38 SELECT MAX(salary),department_id 39 FROM employees 40 WHERE email LIKE '%a%' 41 GROUP BY department_id; 42 43 #案例2:查询有奖金的每个领导手下员工的平均工资 44 SELECT AVG(salary),manager_id 45 FROM employees 46 WHERE commission_pct IS NOT NULL 47 GROUP BY manager_id; 48 49 #3、分组后筛选 50 #案例:查询哪个部门的员工个数>5 51 #①查询每个部门的员工个数 52 SELECT COUNT(*),department_id 53 FROM employees 54 GROUP BY department_id; 55 #② 筛选刚才①结果 56 SELECT COUNT(*),department_id 57 FROM employees 58 GROUP BY department_id 59 HAVING COUNT(*)>5; 60 61 #案例2:每个工种有奖金的员工的最高工资>12000的工种编号和最高工资 62 SELECT job_id,MAX(salary) 63 FROM employees 64 WHERE commission_pct IS NOT NULL 65 GROUP BY job_id 66 HAVING MAX(salary)>12000; 67 68 #案例3:领导编号>102的每个领导手下的最低工资大于5000的领导编号和最低工资 69 manager_id>102 70 SELECT manager_id,MIN(salary) 71 FROM employees 72 GROUP BY manager_id 73 HAVING MIN(salary)>5000; 74 75 #4.添加排序 76 #案例:每个工种有奖金的员工的最高工资>6000的工种编号和最高工资,按最高工资升序 77 SELECT job_id,MAX(salary) m 78 FROM employees 79 WHERE commission_pct IS NOT NULL 80 GROUP BY job_id 81 HAVING m>6000 82 ORDER BY m ; 83 84 #5.按多个字段分组 85 #案例:查询每个工种每个部门的最低工资,并按最低工资降序 86 SELECT MIN(salary),job_id,department_id 87 FROM employees 88 GROUP BY department_id,job_id 89 ORDER BY MIN(salary) DESC;
【案例讲解】分组查询
1 #1.查询各job_id的员工工资的最大值,最小值,平均值,总和,并按job_id升序 2 SELECT MAX(salary),MIN(salary),AVG(salary),SUM(salary),job_id 3 FROM employees 4 GROUP BY job_id 5 ORDER BY job_id; 6 7 #2.查询员工最高工资和最低工资的差距(DIFFERENCE) 8 SELECT MAX(salary)-MIN(salary) DIFFRENCE 9 FROM employees; 10 #3.查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的员工不计算在内 11 SELECT MIN(salary),manager_id 12 FROM employees 13 WHERE manager_id IS NOT NULL 14 GROUP BY manager_id 15 HAVING MIN(salary)>=6000; 16 17 #4.查询所有部门的编号,员工数量和工资平均值,并按平均工资降序 18 SELECT department_id,COUNT(*),AVG(salary) a 19 FROM employees 20 GROUP BY department_id 21 ORDER BY a DESC; 22 #5.选择具有各个job_id的员工人数 23 SELECT COUNT(*) 个数,job_id 24 FROM employees 25 GROUP BY job_id;
六、连接查询
一、含义
连接查询又称多表查询,当查询的字段来自于多个表时,就会用到连接查询
笛卡尔乘积现象:表1 有m行,表2有n行,结果=m*n行
发生原因:没有有效的连接条件
如何避免:添加有效的连接条件
笛卡尔乘积:当查询多个表时,没有添加有效的连接条件,导致多个表所有行实现完全连接
如何解决:添加有效的连接条件
二、分类
按年代分类:
sql92:
等值、非等值、自连接
也支持一部分外连接(用于oracle、sqlserver,mysql不支持)
sql99【推荐使用】
内连接:等值、非等值、自连接
外连接:左外、右外、全外(mysql不支持)
交叉连接
三、SQL92语法
1、等值连接
语法:
select 查询列表
from 表1 别名,表2 别名
where 表1.key=表2.key
【and 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】
特点:
① 一般为表起别名
②多表的顺序可以调换
③n表连接至少需要n-1个连接条件
④等值连接的结果是多表的交集部分
2、非等值连接
语法:
select 查询列表
from 表1 别名,表2 别名
where 非等值的连接条件
【and 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】
3、自连接
语法:
select 查询列表
from 表 别名1,表 别名2
where 等值的连接条件
【and 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】
四、SQL99语法
1、内连接
语法:
select 查询列表
from 表1 别名
【inner】 join 表2 别名 on 连接条件
where 筛选条件
group by 分组列表
having 分组后的筛选
order by 排序列表
limit 子句;
特点:
①表的顺序可以调换
②内连接的结果=多表的交集
③n表连接至少需要n-1个连接条件
分类:
等值连接
非等值连接
自连接
2、外连接
语法:
select 查询列表
from 表1 别名
left|right|full【outer】 join 表2 别名 on 连接条件
where 筛选条件
group by 分组列表
having 分组后的筛选
order by 排序列表
limit 子句;
特点:
①查询的结果=主表中所有的行,如果从表和它匹配的将显示匹配行,如果从表没有匹配的则显示null
②left join 左边的就是主表,right join 右边的就是主表
full join 两边都是主表
③一般用于查询除了交集部分的剩余的不匹配的行
3、交叉连接
语法:
select 查询列表
from 表1 别名
cross join 表2 别名;
特点:
类似于笛卡尔乘积
1 SELECT * FROM beauty; 2 SELECT * FROM boys; 3 4 SELECT NAME,boyName FROM boys,beauty 5 WHERE beauty.boyfriend_id= boys.id; 6 #一、sql92标准 7 #1、等值连接 8 /* 9 ① 多表等值连接的结果为多表的交集部分 10 ②n表连接,至少需要n-1个连接条件 11 ③ 多表的顺序没有要求 12 ④一般需要为表起别名 13 ⑤可以搭配前面介绍的所有子句使用,比如排序、分组、筛选 14 */ 15 16 #案例1:查询女神名和对应的男神名 17 SELECT NAME,boyName 18 FROM boys,beauty 19 WHERE beauty.boyfriend_id= boys.id; 20 #案例2:查询员工名和对应的部门名 21 SELECT last_name,department_name 22 FROM employees,departments 23 WHERE employees.`department_id`=departments.`department_id`; 24 25 #2、为表起别名 26 /* 27 ①提高语句的简洁度 28 ②区分多个重名的字段 29 注意:如果为表起了别名,则查询的字段就不能使用原来的表名去限定 30 */ 31 #查询员工名、工种号、工种名 32 SELECT e.last_name,e.job_id,j.job_title 33 FROM employees e,jobs j 34 WHERE e.`job_id`=j.`job_id`; 35 36 #3、两个表的顺序是否可以调换 37 #查询员工名、工种号、工种名 38 SELECT e.last_name,e.job_id,j.job_title 39 FROM jobs j,employees e 40 WHERE e.`job_id`=j.`job_id`; 41 42 #4、可以加筛选 43 44 #案例:查询有奖金的员工名、部门名 45 SELECT last_name,department_name,commission_pct 46 FROM employees e,departments d 47 WHERE e.`department_id`=d.`department_id` 48 AND e.`commission_pct` IS NOT NULL; 49 #案例2:查询城市名中第二个字符为o的部门名和城市名 50 SELECT department_name,city 51 FROM departments d,locations l 52 WHERE d.`location_id` = l.`location_id` 53 AND city LIKE '_o%'; 54 #5、可以加分组 55 56 #案例1:查询每个城市的部门个数 57 SELECT COUNT(*) 个数,city 58 FROM departments d,locations l 59 WHERE d.`location_id`=l.`location_id` 60 GROUP BY city; 61 62 #案例2:查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资 63 SELECT department_name,d.`manager_id`,MIN(salary) 64 FROM departments d,employees e 65 WHERE d.`department_id`=e.`department_id` 66 AND commission_pct IS NOT NULL 67 GROUP BY department_name,d.`manager_id`; 68 #6、可以加排序 69 70 #案例:查询每个工种的工种名和员工的个数,并且按员工个数降序 71 SELECT job_title,COUNT(*) 72 FROM employees e,jobs j 73 WHERE e.`job_id`=j.`job_id` 74 GROUP BY job_title 75 ORDER BY COUNT(*) DESC; 76 77 #7、可以实现三表连接? 78 #案例:查询员工名、部门名和所在的城市 79 SELECT last_name,department_name,city 80 FROM employees e,departments d,locations l 81 WHERE e.`department_id`=d.`department_id` 82 AND d.`location_id`=l.`location_id` 83 AND city LIKE 's%' 84 ORDER BY department_name DESC; 85 86 #2、非等值连接 87 88 #案例1:查询员工的工资和工资级别 89 90 SELECT salary,grade_level 91 FROM employees e,job_grades g 92 WHERE salary BETWEEN g.`lowest_sal` AND g.`highest_sal` 93 AND g.`grade_level`='A'; 94 /* 95 select salary,employee_id from employees; 96 select * from job_grades; 97 CREATE TABLE job_grades 98 (grade_level VARCHAR(3), 99 lowest_sal int, 100 highest_sal int); 101 INSERT INTO job_grades 102 VALUES ('A', 1000, 2999); 103 INSERT INTO job_grades 104 VALUES ('B', 3000, 5999); 105 INSERT INTO job_grades 106 VALUES('C', 6000, 9999); 107 INSERT INTO job_grades 108 VALUES('D', 10000, 14999); 109 INSERT INTO job_grades 110 VALUES('E', 15000, 24999); 111 INSERT INTO job_grades 112 VALUES('F', 25000, 40000); 113 */ 114 115 116 #3、自连接 117 118 #案例:查询 员工名和上级的名称 119 SELECT e.employee_id,e.last_name,m.employee_id,m.last_name 120 FROM employees e,employees m 121 WHERE e.`manager_id`=m.`employee_id`;
1 二、sql99语法 2 /* 3 语法: 4 select 查询列表 5 from 表1 别名 【连接类型】 6 join 表2 别名 7 on 连接条件 8 【where 筛选条件】 9 【group by 分组】 10 【having 筛选条件】 11 【order by 排序列表】 12 13 分类: 14 内连接(★):inner 15 外连接 16 左外(★):left 【outer】 17 右外(★):right 【outer】 18 全外:full【outer】 19 交叉连接:cross 20 */ 21 22 #一)内连接 23 /* 24 语法: 25 select 查询列表 26 from 表1 别名 27 inner join 表2 别名 28 on 连接条件; 29 分类: 30 等值 31 非等值 32 自连接 33 特点: 34 ①添加排序、分组、筛选 35 ②inner可以省略 36 ③ 筛选条件放在where后面,连接条件放在on后面,提高分离性,便于阅读 37 ④inner join连接和sql92语法中的等值连接效果是一样的,都是查询多表的交集 38 */ 39 40 #1、等值连接 41 #案例1.查询员工名、部门名 42 SELECT last_name,department_name 43 FROM departments d 44 JOIN employees e 45 ON e.`department_id` = d.`department_id`; 46 47 #案例2.查询名字中包含e的员工名和工种名(添加筛选) 48 SELECT last_name,job_title 49 FROM employees e 50 INNER JOIN jobs j 51 ON e.`job_id`= j.`job_id` 52 WHERE e.`last_name` LIKE '%e%'; 53 54 #3. 查询部门个数>3的城市名和部门个数,(添加分组+筛选) 55 #①查询每个城市的部门个数 56 #②在①结果上筛选满足条件的 57 SELECT city,COUNT(*) 部门个数 58 FROM departments d 59 INNER JOIN locations l 60 ON d.`location_id`=l.`location_id` 61 GROUP BY city 62 HAVING COUNT(*)>3; 63 64 #案例4.查询哪个部门的员工个数>3的部门名和员工个数,并按个数降序(添加排序) 65 #①查询每个部门的员工个数 66 SELECT COUNT(*),department_name 67 FROM employees e 68 INNER JOIN departments d 69 ON e.`department_id`=d.`department_id` 70 GROUP BY department_name 71 #② 在①结果上筛选员工个数>3的记录,并排序 72 SELECT COUNT(*) 个数,department_name 73 FROM employees e 74 INNER JOIN departments d 75 ON e.`department_id`=d.`department_id` 76 GROUP BY department_name 77 HAVING COUNT(*)>3 78 ORDER BY COUNT(*) DESC; 79 #5.查询员工名、部门名、工种名,并按部门名降序(添加三表连接) 80 SELECT last_name,department_name,job_title 81 FROM employees e 82 INNER JOIN departments d ON e.`department_id`=d.`department_id` 83 INNER JOIN jobs j ON e.`job_id` = j.`job_id` 84 ORDER BY department_name DESC; 85 #二)非等值连接 86 #查询员工的工资级别 87 SELECT salary,grade_level 88 FROM employees e 89 JOIN job_grades g 90 ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`; 91 #查询工资级别的个数>20的个数,并且按工资级别降序 92 SELECT COUNT(*),grade_level 93 FROM employees e 94 JOIN job_grades g 95 ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal` 96 GROUP BY grade_level 97 HAVING COUNT(*)>20 98 ORDER BY grade_level DESC; 99 #三)自连接 100 #查询员工的名字、上级的名字 101 SELECT e.last_name,m.last_name 102 FROM employees e 103 JOIN employees m 104 ON e.`manager_id`= m.`employee_id`; 105 #查询姓名中包含字符k的员工的名字、上级的名字 106 SELECT e.last_name,m.last_name 107 FROM employees e 108 JOIN employees m 109 ON e.`manager_id`= m.`employee_id` 110 WHERE e.`last_name` LIKE '%k%'; 111 112 #二、外连接 113 /* 114 应用场景:用于查询一个表中有,另一个表没有的记录 115 特点: 116 1、外连接的查询结果为主表中的所有记录 117 如果从表中有和它匹配的,则显示匹配的值 118 如果从表中没有和它匹配的,则显示null 119 外连接查询结果=内连接结果+主表中有而从表没有的记录 120 2、左外连接,left join左边的是主表 121 右外连接,right join右边的是主表 122 3、左外和右外交换两个表的顺序,可以实现同样的效果 123 4、全外连接=内连接的结果+表1中有但表2没有的+表2中有但表1没有的 124 */ 125 #引入:查询男朋友 不在男神表的的女神名 126 SELECT * FROM beauty; 127 SELECT * FROM boys; 128 #左外连接 129 SELECT b.*,bo.* 130 FROM boys bo 131 LEFT OUTER JOIN beauty b 132 ON b.`boyfriend_id` = bo.`id` 133 WHERE b.`id` IS NULL; 134 #案例1:查询哪个部门没有员工 135 #左外 136 SELECT d.*,e.employee_id 137 FROM departments d 138 LEFT OUTER JOIN employees e 139 ON d.`department_id` = e.`department_id` 140 WHERE e.`employee_id` IS NULL; 141 #右外 142 SELECT d.*,e.employee_id 143 FROM employees e 144 RIGHT OUTER JOIN departments d 145 ON d.`department_id` = e.`department_id` 146 WHERE e.`employee_id` IS NULL; 147 #全外 148 USE girls; 149 SELECT b.*,bo.* 150 FROM beauty b 151 FULL OUTER JOIN boys bo 152 ON b.`boyfriend_id` = bo.id;
【案例讲解】外连接
1 #一、查询编号>3的女神的男朋友信息,如果有则列出详细,如果没有,用null填充 2 SELECT b.id,b.name,bo.* 3 FROM beauty b 4 LEFT OUTER JOIN boys bo 5 ON b.`boyfriend_id` = bo.`id` 6 WHERE b.`id`>3; 7 #二、查询哪个城市没有部门 8 SELECT city 9 FROM departments d 10 RIGHT OUTER JOIN locations l 11 ON d.`location_id`=l.`location_id` 12 WHERE d.`department_id` IS NULL; 13 #三、查询部门名为SAL或IT的员工信息 14 SELECT e.*,d.department_name,d.`department_id` 15 FROM departments d 16 LEFT JOIN employees e 17 ON d.`department_id` = e.`department_id` 18 WHERE d.`department_name` IN('SAL','IT'); 19 20 SELECT * FROM departments 21 WHERE `department_name` IN('SAL','IT');
【作业讲解】连接查询
1 #1.显示所有员工的姓名,部门号和部门名称。 2 USE myemployees; 3 SELECT last_name,d.department_id,department_name 4 FROM employees e,departments d 5 WHERE e.`department_id` = d.`department_id`; 6 7 #2.查询90号部门员工的job_id和90号部门的location_id 8 SELECT job_id,location_id 9 FROM employees e,departments d 10 WHERE e.`department_id`=d.`department_id` 11 AND e.`department_id`=90; 12 13 #3. 选择所有有奖金的员工的 14 last_name , department_name , location_id , city 15 16 SELECT last_name , department_name , l.location_id , city 17 FROM employees e,departments d,locations l 18 WHERE e.department_id = d.department_id 19 AND d.location_id=l.location_id 20 AND e.commission_pct IS NOT NULL; 21 22 #4.选择city在Toronto工作的员工的 23 last_name , job_id , department_id , department_name 24 SELECT last_name , job_id , d.department_id , department_name 25 FROM employees e,departments d ,locations l 26 WHERE e.department_id = d.department_id 27 AND d.location_id=l.location_id 28 AND city = 'Toronto'; 29 30 #5.查询每个工种、每个部门的部门名、工种名和最低工资 31 SELECT department_name,job_title,MIN(salary) 最低工资 32 FROM employees e,departments d,jobs j 33 WHERE e.`department_id`=d.`department_id` 34 AND e.`job_id`=j.`job_id` 35 GROUP BY department_name,job_title; 36 37 #6.查询每个国家下的部门个数大于2的国家编号 38 SELECT country_id,COUNT(*) 部门个数 39 FROM departments d,locations l 40 WHERE d.`location_id`=l.`location_id` 41 GROUP BY country_id 42 HAVING 部门个数>2; 43 44 #7、选择指定员工的姓名,员工号,以及他的管理者的姓名和员工号,结果类似于下面的格式 45 employees Emp# manager Mgr# 46 kochhar 101 king 100 47 48 SELECT e.last_name employees,e.employee_id "Emp#",m.last_name manager,m.employee_id "Mgr#" 49 FROM employees e,employees m 50 WHERE e.manager_id = m.employee_id 51 AND e.last_name='kochhar';
七、子查询
一、含义
嵌套在其他语句内部的select语句称为子查询或内查询,
外面的语句可以是insert、update、delete、select等,一般select作为外面语句较多
外面如果为select语句,则此语句称为外查询或主查询
二、分类
1、按出现位置
select后面:
仅仅支持标量子查询
from后面:
表子查询
where或having后面:
标量子查询
列子查询
行子查询
exists后面:
标量子查询
列子查询
行子查询
表子查询
2、按结果集的行列
标量子查询(单行子查询):结果集为一行一列
列子查询(多行子查询):结果集为多行一列
行子查询:结果集为多行多列
表子查询:结果集为多行多列
三、示例
where或having后面
1 1、标量子查询 2 3 案例:查询最低工资的员工姓名和工资 4 5 ①最低工资 6 7 select min(salary) from employees 8 9 10 11 ②查询员工的姓名和工资,要求工资=① 12 13 select last_name,salary 14 15 from employees 16 17 where salary=( 18 19 select min(salary) from employees 20 21 ); 22 23 24 25 2、列子查询 26 27 案例:查询所有是领导的员工姓名 28 29 ①查询所有员工的 manager_id 30 31 select manager_id 32 33 from employees 34 35 36 37 ②查询姓名,employee_id属于①列表的一个 38 39 select last_name 40 41 from employees 42 43 where employee_id in( 44 45 select manager_id 46 47 from employees 48 49 );
1 /* 2 含义: 3 出现在其他语句中的select语句,称为子查询或内查询 4 外部的查询语句,称为主查询或外查询 5 分类: 6 按子查询出现的位置: 7 select后面: 8 仅仅支持标量子查询 9 10 from后面: 11 支持表子查询 12 where或having后面:★ 13 标量子查询(单行) √ 14 列子查询 (多行) √ 15 16 行子查询 17 18 exists后面(相关子查询) 19 表子查询 20 按结果集的行列数不同: 21 标量子查询(结果集只有一行一列) 22 列子查询(结果集只有一列多行) 23 行子查询(结果集有一行多列) 24 表子查询(结果集一般为多行多列) 25 26 27 */ 28 29 #一、where或having后面 30 /* 31 1、标量子查询(单行子查询) 32 2、列子查询(多行子查询) 33 3、行子查询(多列多行) 34 特点: 35 ①子查询放在小括号内 36 ②子查询一般放在条件的右侧 37 ③标量子查询,一般搭配着单行操作符使用 38 > < >= <= = <> 39 列子查询,一般搭配着多行操作符使用 40 in、any/some、all 41 ④子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果 42 */ 43 #1.标量子查询★ 44 #案例1:谁的工资比 Abel 高? 45 #①查询Abel的工资 46 SELECT salary 47 FROM employees 48 WHERE last_name = 'Abel' 49 #②查询员工的信息,满足 salary>①结果 50 SELECT * 51 FROM employees 52 WHERE salary>( 53 SELECT salary 54 FROM employees 55 WHERE last_name = 'Abel' 56 ); 57 #案例2:返回job_id与141号员工相同,salary比143号员工多的员工 姓名,job_id 和工资 58 #①查询141号员工的job_id 59 SELECT job_id 60 FROM employees 61 WHERE employee_id = 141 62 #②查询143号员工的salary 63 SELECT salary 64 FROM employees 65 WHERE employee_id = 143 66 #③查询员工的姓名,job_id 和工资,要求job_id=①并且salary>② 67 SELECT last_name,job_id,salary 68 FROM employees 69 WHERE job_id = ( 70 SELECT job_id 71 FROM employees 72 WHERE employee_id = 141 73 ) AND salary>( 74 SELECT salary 75 FROM employees 76 WHERE employee_id = 143 77 ); 78 79 #案例3:返回公司工资最少的员工的last_name,job_id和salary 80 #①查询公司的 最低工资 81 SELECT MIN(salary) 82 FROM employees 83 #②查询last_name,job_id和salary,要求salary=① 84 SELECT last_name,job_id,salary 85 FROM employees 86 WHERE salary=( 87 SELECT MIN(salary) 88 FROM employees 89 ); 90 91 #案例4:查询最低工资大于50号部门最低工资的部门id和其最低工资 92 #①查询50号部门的最低工资 93 SELECT MIN(salary) 94 FROM employees 95 WHERE department_id = 50 96 #②查询每个部门的最低工资 97 SELECT MIN(salary),department_id 98 FROM employees 99 GROUP BY department_id 100 #③ 在②基础上筛选,满足min(salary)>① 101 SELECT MIN(salary),department_id 102 FROM employees 103 GROUP BY department_id 104 HAVING MIN(salary)>( 105 SELECT MIN(salary) 106 FROM employees 107 WHERE department_id = 50 108 109 ); 110 #非法使用标量子查询 111 SELECT MIN(salary),department_id 112 FROM employees 113 GROUP BY department_id 114 HAVING MIN(salary)>( 115 SELECT salary 116 FROM employees 117 WHERE department_id = 250 118 119 ); 120 121 122 #2.列子查询(多行子查询)★ 123 #案例1:返回location_id是1400或1700的部门中的所有员工姓名 124 #①查询location_id是1400或1700的部门编号 125 SELECT DISTINCT department_id 126 FROM departments 127 WHERE location_id IN(1400,1700) 128 #②查询员工姓名,要求部门号是①列表中的某一个 129 SELECT last_name 130 FROM employees 131 WHERE department_id <>ALL( 132 SELECT DISTINCT department_id 133 FROM departments 134 WHERE location_id IN(1400,1700) 135 136 ); 137 138 #案例2:返回其它工种中比job_id为‘IT_PROG’工种任一工资低的员工的员工号、姓名、job_id 以及salary 139 #①查询job_id为‘IT_PROG’部门任一工资 140 SELECT DISTINCT salary 141 FROM employees 142 WHERE job_id = 'IT_PROG' 143 #②查询员工号、姓名、job_id 以及salary,salary<(①)的任意一个 144 SELECT last_name,employee_id,job_id,salary 145 FROM employees 146 WHERE salary<ANY( 147 SELECT DISTINCT salary 148 FROM employees 149 WHERE job_id = 'IT_PROG' 150 ) AND job_id<>'IT_PROG'; 151 #或 152 SELECT last_name,employee_id,job_id,salary 153 FROM employees 154 WHERE salary<( 155 SELECT MAX(salary) 156 FROM employees 157 WHERE job_id = 'IT_PROG' 158 ) AND job_id<>'IT_PROG'; 159 160 #案例3:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工 的员工号、姓名、job_id 以及salary 161 SELECT last_name,employee_id,job_id,salary 162 FROM employees 163 WHERE salary<ALL( 164 SELECT DISTINCT salary 165 FROM employees 166 WHERE job_id = 'IT_PROG' 167 ) AND job_id<>'IT_PROG'; 168 #或 169 SELECT last_name,employee_id,job_id,salary 170 FROM employees 171 WHERE salary<( 172 SELECT MIN( salary) 173 FROM employees 174 WHERE job_id = 'IT_PROG' 175 ) AND job_id<>'IT_PROG'; 176 177 178 #3、行子查询(结果集一行多列或多行多列) 179 #案例:查询员工编号最小并且工资最高的员工信息 180 181 182 SELECT * 183 FROM employees 184 WHERE (employee_id,salary)=( 185 SELECT MIN(employee_id),MAX(salary) 186 FROM employees 187 ); 188 #①查询最小的员工编号 189 SELECT MIN(employee_id) 190 FROM employees 191 192 #②查询最高工资 193 SELECT MAX(salary) 194 FROM employees 195 196 #③查询员工信息 197 SELECT * 198 FROM employees 199 WHERE employee_id=( 200 SELECT MIN(employee_id) 201 FROM employees 202 203 )AND salary=( 204 SELECT MAX(salary) 205 FROM employees 206 ); 207 208 #二、select后面 209 /* 210 仅仅支持标量子查询 211 */ 212 #案例:查询每个部门的员工个数 213 214 SELECT d.*,( 215 SELECT COUNT(*) 216 FROM employees e 217 WHERE e.department_id = d.`department_id` 218 ) 个数 219 FROM departments d; 220 #案例2:查询员工号=102的部门名 221 SELECT ( 222 SELECT department_name,e.department_id 223 FROM departments d 224 INNER JOIN employees e 225 ON d.department_id=e.department_id 226 WHERE e.employee_id=102 227 228 ) 部门名; 229 230 231 #三、from后面 232 /* 233 将子查询结果充当一张表,要求必须起别名 234 */ 235 #案例:查询每个部门的平均工资的工资等级 236 #①查询每个部门的平均工资 237 SELECT AVG(salary),department_id 238 FROM employees 239 GROUP BY department_id 240 241 SELECT * FROM job_grades; 242 243 #②连接①的结果集和job_grades表,筛选条件平均工资 between lowest_sal and highest_sal 244 SELECT ag_dep.*,g.`grade_level` 245 FROM ( 246 SELECT AVG(salary) ag,department_id 247 FROM employees 248 GROUP BY department_id 249 ) ag_dep 250 INNER JOIN job_grades g 251 ON ag_dep.ag BETWEEN lowest_sal AND highest_sal; 252 253 254 #四、exists后面(相关子查询) 255 /* 256 语法: 257 exists(完整的查询语句) 258 结果: 259 1或0 260 261 262 */ 263 SELECT EXISTS(SELECT employee_id FROM employees WHERE salary=300000); 264 #案例1:查询有员工的部门名 265 #in 266 SELECT department_name 267 FROM departments d 268 WHERE d.`department_id` IN( 269 SELECT department_id 270 FROM employees 271 ) 272 #exists 273 SELECT department_name 274 FROM departments d 275 WHERE EXISTS( 276 SELECT * 277 FROM employees e 278 WHERE d.`department_id`=e.`department_id` 279 280 ); 281 282 #案例2:查询没有女朋友的男神信息 283 #in 284 SELECT bo/* 285 含义: 286 出现在其他语句中的select语句,称为子查询或内查询 287 外部的查询语句,称为主查询或外查询 288 分类: 289 按子查询出现的位置: 290 select后面: 291 仅仅支持标量子查询 292 293 from后面: 294 支持表子查询 295 where或having后面:★ 296 标量子查询(单行) √ 297 列子查询 (多行) √ 298 299 行子查询 300 301 exists后面(相关子查询) 302 表子查询 303 按结果集的行列数不同: 304 标量子查询(结果集只有一行一列) 305 列子查询(结果集只有一列多行) 306 行子查询(结果集有一行多列) 307 表子查询(结果集一般为多行多列) 308 309 310 */ 311 312 #一、where或having后面 313 /* 314 1、标量子查询(单行子查询) 315 2、列子查询(多行子查询) 316 3、行子查询(多列多行) 317 特点: 318 ①子查询放在小括号内 319 ②子查询一般放在条件的右侧 320 ③标量子查询,一般搭配着单行操作符使用 321 > < >= <= = <> 322 列子查询,一般搭配着多行操作符使用 323 in、any/some、all 324 ④子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果 325 */ 326 #1.标量子查询★ 327 #案例1:谁的工资比 Abel 高? 328 #①查询Abel的工资 329 SELECT salary 330 FROM employees 331 WHERE last_name = 'Abel' 332 #②查询员工的信息,满足 salary>①结果 333 SELECT * 334 FROM employees 335 WHERE salary>( 336 SELECT salary 337 FROM employees 338 WHERE last_name = 'Abel' 339 ); 340 #案例2:返回job_id与141号员工相同,salary比143号员工多的员工 姓名,job_id 和工资 341 #①查询141号员工的job_id 342 SELECT job_id 343 FROM employees 344 WHERE employee_id = 141 345 #②查询143号员工的salary 346 SELECT salary 347 FROM employees 348 WHERE employee_id = 143 349 #③查询员工的姓名,job_id 和工资,要求job_id=①并且salary>② 350 SELECT last_name,job_id,salary 351 FROM employees 352 WHERE job_id = ( 353 SELECT job_id 354 FROM employees 355 WHERE employee_id = 141 356 ) AND salary>( 357 SELECT salary 358 FROM employees 359 WHERE employee_id = 143 360 ); 361 362 #案例3:返回公司工资最少的员工的last_name,job_id和salary 363 #①查询公司的 最低工资 364 SELECT MIN(salary) 365 FROM employees 366 #②查询last_name,job_id和salary,要求salary=① 367 SELECT last_name,job_id,salary 368 FROM employees 369 WHERE salary=( 370 SELECT MIN(salary) 371 FROM employees 372 ); 373 374 #案例4:查询最低工资大于50号部门最低工资的部门id和其最低工资 375 #①查询50号部门的最低工资 376 SELECT MIN(salary) 377 FROM employees 378 WHERE department_id = 50 379 #②查询每个部门的最低工资 380 SELECT MIN(salary),department_id 381 FROM employees 382 GROUP BY department_id 383 #③ 在②基础上筛选,满足min(salary)>① 384 SELECT MIN(salary),department_id 385 FROM employees 386 GROUP BY department_id 387 HAVING MIN(salary)>( 388 SELECT MIN(salary) 389 FROM employees 390 WHERE department_id = 50 391 392 ); 393 #非法使用标量子查询 394 SELECT MIN(salary),department_id 395 FROM employees 396 GROUP BY department_id 397 HAVING MIN(salary)>( 398 SELECT salary 399 FROM employees 400 WHERE department_id = 250 401 402 ); 403 404 405 #2.列子查询(多行子查询)★ 406 #案例1:返回location_id是1400或1700的部门中的所有员工姓名 407 #①查询location_id是1400或1700的部门编号 408 SELECT DISTINCT department_id 409 FROM departments 410 WHERE location_id IN(1400,1700) 411 #②查询员工姓名,要求部门号是①列表中的某一个 412 SELECT last_name 413 FROM employees 414 WHERE department_id <>ALL( 415 SELECT DISTINCT department_id 416 FROM departments 417 WHERE location_id IN(1400,1700) 418 419 ); 420 421 #案例2:返回其它工种中比job_id为‘IT_PROG’工种任一工资低的员工的员工号、姓名、job_id 以及salary 422 #①查询job_id为‘IT_PROG’部门任一工资 423 SELECT DISTINCT salary 424 FROM employees 425 WHERE job_id = 'IT_PROG' 426 #②查询员工号、姓名、job_id 以及salary,salary<(①)的任意一个 427 SELECT last_name,employee_id,job_id,salary 428 FROM employees 429 WHERE salary<ANY( 430 SELECT DISTINCT salary 431 FROM employees 432 WHERE job_id = 'IT_PROG' 433 ) AND job_id<>'IT_PROG'; 434 #或 435 SELECT last_name,employee_id,job_id,salary 436 FROM employees 437 WHERE salary<( 438 SELECT MAX(salary) 439 FROM employees 440 WHERE job_id = 'IT_PROG' 441 ) AND job_id<>'IT_PROG'; 442 443 #案例3:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工 的员工号、姓名、job_id 以及salary 444 SELECT last_name,employee_id,job_id,salary 445 FROM employees 446 WHERE salary<ALL( 447 SELECT DISTINCT salary 448 FROM employees 449 WHERE job_id = 'IT_PROG' 450 ) AND job_id<>'IT_PROG'; 451 #或 452 SELECT last_name,employee_id,job_id,salary 453 FROM employees 454 WHERE salary<( 455 SELECT MIN( salary) 456 FROM employees 457 WHERE job_id = 'IT_PROG' 458 ) AND job_id<>'IT_PROG'; 459 460 461 #3、行子查询(结果集一行多列或多行多列) 462 #案例:查询员工编号最小并且工资最高的员工信息 463 464 465 SELECT * 466 FROM employees 467 WHERE (employee_id,salary)=( 468 SELECT MIN(employee_id),MAX(salary) 469 FROM employees 470 ); 471 #①查询最小的员工编号 472 SELECT MIN(employee_id) 473 FROM employees 474 475 #②查询最高工资 476 SELECT MAX(salary) 477 FROM employees 478 479 #③查询员工信息 480 SELECT * 481 FROM employees 482 WHERE employee_id=( 483 SELECT MIN(employee_id) 484 FROM employees 485 486 )AND salary=( 487 SELECT MAX(salary) 488 FROM employees 489 ); 490 491 #二、select后面 492 /* 493 仅仅支持标量子查询 494 */ 495 #案例:查询每个部门的员工个数 496 497 SELECT d.*,( 498 SELECT COUNT(*) 499 FROM employees e 500 WHERE e.department_id = d.`department_id` 501 ) 个数 502 FROM departments d; 503 #案例2:查询员工号=102的部门名 504 SELECT ( 505 SELECT department_name,e.department_id 506 FROM departments d 507 INNER JOIN employees e 508 ON d.department_id=e.department_id 509 WHERE e.employee_id=102 510 511 ) 部门名; 512 513 514 #三、from后面 515 /* 516 将子查询结果充当一张表,要求必须起别名 517 */ 518 #案例:查询每个部门的平均工资的工资等级 519 #①查询每个部门的平均工资 520 SELECT AVG(salary),department_id 521 FROM employees 522 GROUP BY department_id 523 524 SELECT * FROM job_grades; 525 526 #②连接①的结果集和job_grades表,筛选条件平均工资 between lowest_sal and highest_sal 527 SELECT ag_dep.*,g.`grade_level` 528 FROM ( 529 SELECT AVG(salary) ag,department_id 530 FROM employees 531 GROUP BY department_id 532 ) ag_dep 533 INNER JOIN job_grades g 534 ON ag_dep.ag BETWEEN lowest_sal AND highest_sal; 535 536 537 #四、exists后面(相关子查询) 538 /* 539 语法: 540 exists(完整的查询语句) 541 结果: 542 1或0 543 544 545 */ 546 SELECT EXISTS(SELECT employee_id FROM employees WHERE salary=300000); 547 #案例1:查询有员工的部门名 548 #in 549 SELECT department_name 550 FROM departments d 551 WHERE d.`department_id` IN( 552 SELECT department_id 553 FROM employees 554 ) 555 #exists 556 SELECT department_name 557 FROM departments d 558 WHERE EXISTS( 559 SELECT * 560 FROM employees e 561 WHERE d.`department_id`=e.`department_id` 562 563 ); 564 565 #案例2:查询没有女朋友的男神信息 566 #in 567 SELECT bo.* 568 FROM boys bo 569 WHERE bo.id NOT IN( 570 SELECT boyfriend_id 571 FROM beauty 572 ) 573 #exists 574 SELECT bo.* 575 FROM boys bo 576 WHERE NOT EXISTS( 577 SELECT boyfriend_id 578 FROM beauty b 579 WHERE bo.`id`=b.`boyfriend_id` 580 );.* 581 FROM boys bo 582 WHERE bo.id NOT IN( 583 SELECT boyfriend_id 584 FROM beauty 585 ) 586 #exists 587 SELECT bo.* 588 FROM boys bo 589 WHERE NOT EXISTS( 590 SELECT boyfriend_id 591 FROM beauty b 592 WHERE bo.`id`=b.`boyfriend_id` 593 );
【案例讲解】子查询
1 #1. 查询和Zlotkey相同部门的员工姓名和工资 2 #①查询Zlotkey的部门 3 SELECT department_id 4 FROM employees 5 WHERE last_name = 'Zlotkey' 6 #②查询部门号=①的姓名和工资 7 SELECT last_name,salary 8 FROM employees 9 WHERE department_id = ( 10 SELECT department_id 11 FROM employees 12 WHERE last_name = 'Zlotkey' 13 ) 14 #2.查询工资比公司平均工资高的员工的员工号,姓名和工资。 15 #①查询平均工资 16 SELECT AVG(salary) 17 FROM employees 18 #②查询工资>①的员工号,姓名和工资。 19 SELECT last_name,employee_id,salary 20 FROM employees 21 WHERE salary>( 22 SELECT AVG(salary) 23 FROM employees 24 ); 25 26 27 #3.查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资 28 #①查询各部门的平均工资 29 SELECT AVG(salary),department_id 30 FROM employees 31 GROUP BY department_id 32 #②连接①结果集和employees表,进行筛选 33 SELECT employee_id,last_name,salary,e.department_id 34 FROM employees e 35 INNER JOIN ( 36 SELECT AVG(salary) ag,department_id 37 FROM employees 38 GROUP BY department_id 39 40 ) ag_dep 41 ON e.department_id = ag_dep.department_id 42 WHERE salary>ag_dep.ag ; 43 44 45 #4. 查询和姓名中包含字母u的员工在相同部门的员工的员工号和姓名 46 #①查询姓名中包含字母u的员工的部门 47 SELECT DISTINCT department_id 48 FROM employees 49 WHERE last_name LIKE '%u%' 50 #②查询部门号=①中的任意一个的员工号和姓名 51 SELECT last_name,employee_id 52 FROM employees 53 WHERE department_id IN( 54 SELECT DISTINCT department_id 55 FROM employees 56 WHERE last_name LIKE '%u%' 57 ); 58 59 #5. 查询在部门的location_id为1700的部门工作的员工的员工号 60 #①查询location_id为1700的部门 61 SELECT DISTINCT department_id 62 FROM departments 63 WHERE location_id = 1700 64 65 #②查询部门号=①中的任意一个的员工号 66 SELECT employee_id 67 FROM employees 68 WHERE department_id =ANY( 69 SELECT DISTINCT department_id 70 FROM departments 71 WHERE location_id = 1700 72 ); 73 #6.查询管理者是King的员工姓名和工资 74 #①查询姓名为king的员工编号 75 SELECT employee_id 76 FROM employees 77 WHERE last_name = 'K_ing' 78 #②查询哪个员工的manager_id = ① 79 SELECT last_name,salary 80 FROM employees 81 WHERE manager_id IN( 82 SELECT employee_id 83 FROM employees 84 WHERE last_name = 'K_ing' 85 ); 86 #7.查询工资最高的员工的姓名,要求first_name和last_name显示为一列,列名为 姓.名 87 88 #①查询最高工资 89 SELECT MAX(salary) 90 FROM employees 91 #②查询工资=①的姓.名 92 SELECT CONCAT(first_name,last_name) "姓.名" 93 FROM employees 94 WHERE salary=( 95 SELECT MAX(salary) 96 FROM employees 97 );
子查询经典案例
1 # 1. 查询工资最低的员工信息: last_name, salary 2 #①查询最低的工资 3 SELECT MIN(salary) 4 FROM employees 5 6 #②查询last_name,salary,要求salary=① 7 SELECT last_name,salary 8 FROM employees 9 WHERE salary=( 10 SELECT MIN(salary) 11 FROM employees 12 ); 13 14 # 2. 查询平均工资最低的部门信息 15 #方式一: 16 #①各部门的平均工资 17 SELECT AVG(salary),department_id 18 FROM employees 19 GROUP BY department_id 20 #②查询①结果上的最低平均工资 21 SELECT MIN(ag) 22 FROM ( 23 SELECT AVG(salary) ag,department_id 24 FROM employees 25 GROUP BY department_id 26 ) ag_dep 27 #③查询哪个部门的平均工资=② 28 SELECT AVG(salary),department_id 29 FROM employees 30 GROUP BY department_id 31 HAVING AVG(salary)=( 32 SELECT MIN(ag) 33 FROM ( 34 SELECT AVG(salary) ag,department_id 35 FROM employees 36 GROUP BY department_id 37 ) ag_dep 38 ); 39 #④查询部门信息 40 SELECT d.* 41 FROM departments d 42 WHERE d.`department_id`=( 43 SELECT department_id 44 FROM employees 45 GROUP BY department_id 46 HAVING AVG(salary)=( 47 SELECT MIN(ag) 48 FROM ( 49 SELECT AVG(salary) ag,department_id 50 FROM employees 51 GROUP BY department_id 52 ) ag_dep 53 ) 54 ); 55 #方式二: 56 #①各部门的平均工资 57 SELECT AVG(salary),department_id 58 FROM employees 59 GROUP BY department_id 60 #②求出最低平均工资的部门编号 61 SELECT department_id 62 FROM employees 63 GROUP BY department_id 64 ORDER BY AVG(salary) 65 LIMIT 1; 66 #③查询部门信息 67 SELECT * 68 FROM departments 69 WHERE department_id=( 70 SELECT department_id 71 FROM employees 72 GROUP BY department_id 73 ORDER BY AVG(salary) 74 LIMIT 1 75 ); 76 77 78 79 # 3. 查询平均工资最低的部门信息和该部门的平均工资 80 #①各部门的平均工资 81 SELECT AVG(salary),department_id 82 FROM employees 83 GROUP BY department_id 84 #②求出最低平均工资的部门编号 85 SELECT AVG(salary),department_id 86 FROM employees 87 GROUP BY department_id 88 ORDER BY AVG(salary) 89 LIMIT 1; 90 #③查询部门信息 91 SELECT d.*,ag 92 FROM departments d 93 JOIN ( 94 SELECT AVG(salary) ag,department_id 95 FROM employees 96 GROUP BY department_id 97 ORDER BY AVG(salary) 98 LIMIT 1 99 ) ag_dep 100 ON d.`department_id`=ag_dep.department_id; 101 102 103 # 4. 查询平均工资最高的 job 信息 104 #①查询最高的job的平均工资 105 SELECT AVG(salary),job_id 106 FROM employees 107 GROUP BY job_id 108 ORDER BY AVG(salary) DESC 109 LIMIT 1 110 #②查询job信息 111 SELECT * 112 FROM jobs 113 WHERE job_id=( 114 SELECT job_id 115 FROM employees 116 GROUP BY job_id 117 ORDER BY AVG(salary) DESC 118 LIMIT 1 119 ); 120 # 5. 查询平均工资高于公司平均工资的部门有哪些? 121 #①查询平均工资 122 SELECT AVG(salary) 123 FROM employees 124 #②查询每个部门的平均工资 125 SELECT AVG(salary),department_id 126 FROM employees 127 GROUP BY department_id 128 #③筛选②结果集,满足平均工资>① 129 SELECT AVG(salary),department_id 130 FROM employees 131 GROUP BY department_id 132 HAVING AVG(salary)>( 133 SELECT AVG(salary) 134 FROM employees 135 ); 136 # 6. 查询出公司中所有 manager 的详细信息. 137 #①查询所有manager的员工编号 138 SELECT DISTINCT manager_id 139 FROM employees 140 #②查询详细信息,满足employee_id=① 141 SELECT * 142 FROM employees 143 WHERE employee_id =ANY( 144 SELECT DISTINCT manager_id 145 FROM employees 146 ); 147 # 7. 各个部门中 最高工资中最低的那个部门的 最低工资是多少 148 #①查询各部门的最高工资中最低的部门编号 149 SELECT department_id 150 FROM employees 151 GROUP BY department_id 152 ORDER BY MAX(salary) 153 LIMIT 1 154 155 #②查询①结果的那个部门的最低工资 156 SELECT MIN(salary) ,department_id 157 FROM employees 158 WHERE department_id=( 159 SELECT department_id 160 FROM employees 161 GROUP BY department_id 162 ORDER BY MAX(salary) 163 LIMIT 1 164 165 ); 166 # 8. 查询平均工资最高的部门的 manager 的详细信息: last_name, department_id, email, salary 167 #①查询平均工资最高的部门编号 168 SELECT 169 department_id 170 FROM 171 employees 172 GROUP BY department_id 173 ORDER BY AVG(salary) DESC 174 LIMIT 1 175 #②将employees和departments连接查询,筛选条件是① 176 SELECT 177 last_name, d.department_id, email, salary 178 FROM 179 employees e 180 INNER JOIN departments d 181 ON d.manager_id = e.employee_id 182 WHERE d.department_id = 183 (SELECT 184 department_id 185 FROM 186 employees 187 GROUP BY department_id 188 ORDER BY AVG(salary) DESC 189 LIMIT 1) ;
八、分页查询
一、应用场景
当要查询的条目数太多,一页显示不全
二、语法
select 查询列表
from 表
limit 【offset,】size;
注意:
offset代表的是起始的条目索引,默认从0卡死
size代表的是显示的条目数
公式:
假如要显示的页数为page,每一页条目数为size
select 查询列表
from 表
limit (page-1)*size,size;
1 /* 2 应用场景:当要显示的数据,一页显示不全,需要分页提交sql请求 3 语法: 4 select 查询列表 5 from 表 6 【join type join 表2 7 on 连接条件 8 where 筛选条件 9 group by 分组字段 10 having 分组后的筛选 11 order by 排序的字段】 12 limit 【offset,】size; 13 14 offset要显示条目的起始索引(起始索引从0开始) 15 size 要显示的条目个数 16 特点: 17 ①limit语句放在查询语句的最后 18 ②公式 19 要显示的页数 page,每页的条目数size 20 21 select 查询列表 22 from 表 23 limit (page-1)*size,size; 24 25 size=10 26 page 27 1 0 28 2 10 29 3 20 30 31 */ 32 #案例1:查询前五条员工信息 33 34 SELECT * FROM employees LIMIT 0,5; 35 SELECT * FROM employees LIMIT 5; 36 37 #案例2:查询第11条——第25条 38 SELECT * FROM employees LIMIT 10,15; 39 40 #案例3:有奖金的员工信息,并且工资较高的前10名显示出来 41 SELECT 42 * 43 FROM 44 employees 45 WHERE commission_pct IS NOT NULL 46 ORDER BY salary DESC 47 LIMIT 10 ;
作业-查询sql
1 #一、查询每个专业的学生人数 2 SELECT majorid,COUNT(*) 3 FROM student 4 GROUP BY majorid; 5 #二、查询参加考试的学生中,每个学生的平均分、最高分 6 SELECT AVG(score),MAX(score),studentno 7 FROM result 8 GROUP BY studentno; 9 #三、查询姓张的每个学生的最低分大于60的学号、姓名 10 SELECT s.studentno,s.`studentname`,MIN(score) 11 FROM student s 12 JOIN result r 13 ON s.`studentno`=r.`studentno` 14 WHERE s.`studentname` LIKE '张%' 15 GROUP BY s.`studentno` 16 HAVING MIN(score)>60; 17 #四、查询每个专业生日在“1988-1-1”后的学生姓名、专业名称 18 SELECT m.`majorname`,s.`studentname` 19 FROM student s 20 JOIN major m 21 ON m.`majorid`=s.`majorid` 22 WHERE DATEDIFF(borndate,'1988-1-1')>0 23 GROUP BY m.`majorid`; 24 25 #五、查询每个专业的男生人数和女生人数分别是多少 26 SELECT COUNT(*),sex,majorid 27 FROM student 28 GROUP BY sex,majorid; 29 #六、查询专业和张翠山一样的学生的最低分 30 #①查询张翠山的专业编号 31 SELECT majorid 32 FROM student 33 WHERE studentname = '张翠山' 34 #②查询编号=①的所有学生编号 35 SELECT studentno 36 FROM student 37 WHERE majorid=( 38 SELECT majorid 39 FROM student 40 WHERE studentname = '张翠山' 41 ) 42 #②查询最低分 43 SELECT MIN(score) 44 FROM result 45 WHERE studentno IN( 46 SELECT studentno 47 FROM student 48 WHERE majorid=( 49 SELECT majorid 50 FROM student 51 WHERE studentname = '张翠山' 52 ) 53 ) 54 #七、查询大于60分的学生的姓名、密码、专业名 55 SELECT studentname,loginpwd,majorname 56 FROM student s 57 JOIN major m ON s.majorid= m.majorid 58 JOIN result r ON s.studentno=r.studentno 59 WHERE r.score>60; 60 #八、按邮箱位数分组,查询每组的学生个数 61 SELECT COUNT(*),LENGTH(email) 62 FROM student 63 GROUP BY LENGTH(email); 64 #九、查询学生名、专业名、分数 65 SELECT studentname,score,majorname 66 FROM student s 67 JOIN major m ON s.majorid= m.majorid 68 LEFT JOIN result r ON s.studentno=r.studentno 69 70 #十、查询哪个专业没有学生,分别用左连接和右连接实现 71 #左 72 SELECT m.`majorid`,m.`majorname`,s.`studentno` 73 FROM major m 74 LEFT JOIN student s ON m.`majorid` = s.`majorid` 75 WHERE s.`studentno` IS NULL; 76 #右 77 SELECT m.`majorid`,m.`majorname`,s.`studentno` 78 FROM student s 79 RIGHT JOIN major m ON m.`majorid` = s.`majorid` 80 WHERE s.`studentno` IS NULL; 81 #十一、查询没有成绩的学生人数 82 SELECT COUNT(*) 83 FROM student s 84 LEFT JOIN result r ON s.`studentno` = r.`studentno` 85 WHERE r.`id` IS NULL
九、联合查询
union 联合 合并:将多条查询语句的结果合并成一个结果
语法:
查询语句1
union
查询语句2
union
...
应用场景:
要查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致时
特点:★
1、要求多条查询语句的查询列数是一致的!
2、要求多条查询语句的查询的每一列的类型和顺序最好一致
3、union关键字默认去重,如果使用union all 可以包含重复项
1 #引入的案例:查询部门编号>90或邮箱包含a的员工信息 2 SELECT * FROM employees WHERE email LIKE '%a%' OR department_id>90;; 3 SELECT * FROM employees WHERE email LIKE '%a%' 4 UNION 5 SELECT * FROM employees WHERE department_id>90; 6 7 #案例:查询中国用户中男性的信息以及外国用户中年男性的用户信息 8 SELECT id,cname FROM t_ca WHERE csex='男' 9 UNION ALL 10 SELECT t_id,tname FROM t_ua WHERE tGender='male';