DQL(Data QueryLanguage)数据查询语言
SELECT 查询列表 FROM 表名
查询列表可以是表中的字段、常量值、表达式、函数
一、基础查询
(1)查询表中的单/多个字段
(2)查询所有字段
(3)查询常量值
(4)查询可以直接使用运算符
(5)查询函数
(6)起别名
(7)未去重
去重
(8)+与concat()
他们两个效果相同
当两个操作数都为数值型则做加法运算
有一方为字符类型,会试图转换为数值类型,转换成功则进行数值运算,转换失败则将字符型视为0,若有一个操作数为NULL则结果为NULL
(9)IFNULL( x,y)
将为NULL的数据转换为给定的值
(10)条件查询
1、按条件表达式筛选
>= <= = != <>(不等于)
eg:查询工资>12000的员工信息
eg:查询部门编号不等于90的员工名和部门号
2、按逻辑表达式筛选
eg:查询工资在10000-20000之间的员工名,工资、奖金率
3、模糊查询
语法:select 查询列表 from 表名 where 筛选条件
模糊查询下划线代表任意单个字符,%代表任意多个字符
eg:查询员工名中包含字符c的员工信息
eg:查询员工名第二个字母为h的员工信息
eg:查询员工们中第二个字符为_的员工名,需要转义
我们也可以在单条语句中自定义转移符号
Beetween and模糊查询
eg:查询员工编号在100-120之间的员工信息
MySQL的between and两边都是闭区间,要注意与Java的左闭右开区分。另外要注意的是between后面的值必须小于等于and后面的值
In模糊查询
eg:查询员工的工种编号是IT_PROG、AD_PRES、AD_VP的员工名和工种编号,需要注意这些字段需要使用引号包含
在使用in模糊查询时需要注意in列表里面的值必须类型一致或兼容(比如字符串类型的数字可以和普通数字兼容),另外in列表中的内容不支持通配符。原因是in这种语法就相当于多个=判断的集合
Is null关键字
当查询的数值为Null时不能使用=Null,只能用is (not) null
eg:查询没有奖金的员工名和奖金率
安全等与<=>
安全等与既可以匹配NULL值也可以匹配普通的值
eg:查询没有奖金的员工的姓名和奖金率
eg:查询奖金率为0.2的员工姓名和奖金率
二、排序查询
基本语法:select 查询列表 from 表名 【where条件】 order by 排序列 【asc|desc】
eg:查询员工信息并按工资从高到低排序
eg:查询员工部门编号>=90的员工信息并按入职时间排序
它默认的排序方式就是升序排序,所以ASC可以省略
eg:按员工姓名长度排序
根据多个字段排序
当根据多个字段排序时会优先按照前面的字段排序,当前一个字段的值相同时再根据后面的字段排序
三、常用函数
函数分为单行函数和分组函数,单行函数主要用于做数据处理,分组函数主要用于统计,所以分组函数又称为统计函数或聚合函数。在学习MySQL函数时我们主要要记住函数名和功能,至于具体用法可以用到的时候百度或者CSDN就有很多总结
单行函数又分为字符函数、数学函数、日期函数、流程控制函数和其他函数
1、length()查询结果的长度
2、concat()拼接字符串
3、upper()、lower()大小写转化
4、substr()、substring()
SQL语言的索引从1开始,并且都是闭区间。Substr()和substring()效果相同
5、instr()返回字串第一次出现的索引,如果找不到返回0
6、trim()去左右空格或左右指定字符串
默认去除空格
如果你去除的字符串全部包含的都是要去除的内容会报错
7、lpad()/rpad()指定长度输出
如果指定的长度本身就超出了给定的字符串,就会从左向右截取指定长度
相对应的还有rpad(),只是在不足的情况下在右边填充,在超出的情况下与lpad()效果相同
8、replace()替换
如果里面匹配了很多个字符串也会全部替换
数学函数
1、round()四舍五入
round()函数的四舍五入只看绝对值
还可以指定保留的位数
2、truncate()截断
将指定小数位后面的数全部舍弃
3、ceil()向上取整
返回大于等于该参数的最小整数
4、floor()向下取整
返回小于等于该参数的最大整数
5、mod()取余
这里需要注意的是MySQL中取余结果的符号位只看被取余数。因为它的计算公式为A-A/B*B
日期函数
1、返回当前系统时间
2、返回当前日期,不包含时间
3、返回当前时间,不会包含日期
4、获取年月日时分秒中特定的部分
eg:查询员工入职年份
还可以用英文显示月份
5、格式化日期
STR_TO_DATE():将字符通过指定的格式转换为日期类型
eg:查看入职日期为1992年4月3日的员工的信息
也可以在这个查询中按指定的日期格式进行查找
DATE_FORMAT()函数:将日期按照指定格式输出,可以在里面加入其他字符信息
求两个日期相差的天数
其他函数
1、查看当前数据库版本
2、查看当前使用的数据库
3、查看当前登录用户
4、加密函数
流程控制中的选择分支结构函数
1、if()函数
语法为if(表达式,TRUE的返回结果,FALSE的返回结果)
2、Case结构
这相当于其他编程语言中的switch case结构。
这里多学一个知识点就是在查询结果中增加自定义的一个描述,注意点是使用end as关键字,还有select列表最后必须使用逗号
分组函数
分组函数又称为聚合函数或统计函数或组函数
特点:
1、sum、avg一般用于处理数值型
2、Max,min,count可以处理任何类型
3、忽略null值
分组函数与distinct配合实现去重统计
另外使用count()查询整个表的数据条数可以使用count(),这样只要有任意一列数据不为NULL的行都会被统计进去,当然也可以使用非空的字段来查询数据总条数,形如count(任意非空字段),也可以用count(1)
区别:
MYISAM存储引擎下,COUNT()的效率高
INNODB存储引擎下,COUNT(*)和COUNT(1)的效率高,比COUNT(字段)效率更高
四、分组查询
1、基本语法
SELECT 分组函数,列(要求出现在group by之后)
FROM 表 【WHERE筛选条件】
GROUP BY 分组列表
ORDER BY【子句】
注意:查询列表必须是分组函数和group by后出现的字段
eg:查询每个工种的最高工资
2、添加筛选条件后分组
eg:查询每个领导下有奖金的员工的最高工资
eg:查询那个部门的员工数大于2
可以看到这里出错了,因为从逻辑上来说这应该是按照分组之后的结果在来进行筛选,所以需要再引进新知识点having,专门用于分组之后的筛选
eg:查询每个领导手下的员工的最低工资
注意区分where筛选与having筛选
3、按函数分组
eg:将员工按姓名长度分组,并筛选处员工个数大于5的分组
这里涉及到一个关于别名的知识点:
对于MySQL:Group by和having后支持别名,where后不支持别名
但是其他的数据库是不支持Group by和having后使用别名的
4、按多个字段进行分组
只有多个字段都相同的才会被分为一组
eg:查询每个部门每个工种员工的平均工资
在此基础上添加排序
五、连接查询
连接查询又称多表查询,当查询的字段来自多个表时就会用到连接查询
像这样查询,每张表的每个元素都会与其他表进行匹配,这种结果称为笛卡尔积。避免笛卡尔积的办法就是添加有效的连接条件。连接查询中有一种交叉查询的结果也是笛卡尔积,了解即可。
连接查询也分为多种。按功能分类有
内连接(等值连接、非等值连接、自连接)、外连接(左外连接、右外连接、全外连接)、交叉连接,其中MySQL不支持全外连接
1、等值连接
eg:查询女生名及对应的男友
eg:查询员工名及对应的部门名
因为这里表名一般很长,而且匹配时还要使用,所以一般会在这里使用到别名
对表使用别名之后也要注意,在连接条件使用别名之后,若是查询的字段也有重复的,也必须使用”表别名.字段名”的方式声明是哪一个字段
等值连接的注意点:
(1)多表等值连接的结果为多表的交集部分
(2)n表连接,至少需要n-1个连接条件
(3)多表的顺序没有要求
(4)一般需要为表起别名
(5)可与之前的所有子句结合使用,如排序、分组、筛选
2、非等值连接
eg:查询员工的姓名、工作及工资状况
3、自连接
如果要查找领导和员工的对应关系,而领导也算是公司的员工,也存储在员工表中,这时就需要多次在一张表中查找,这时候就需要使用到自连接。自连接就需要将一张表当作两张表来看待
eg:查询员工及其领导的名字
4、外连接
外连接分为主表与从表,用从表中的每一条符合要求的信息去匹配主表中每一条信息,也就是主表与从表应该是1(主表)对多(从表)的关系。也可以简单的记为:外连接用于查询一个表中有,而另一个表中没有的记录。除了外连接都是内连接,之前所学的连接也都是内连接。
特点:
1、外连接的查询结果为主表中的所有记录,如果从表中有和它匹配的,则显示匹配的值;如果从表中没有和它匹配的,则显示为NULL。外连接的查询结果=内连接结果+主表中有而从表中没有的记录
2、左外连接,left outer join左边的是主表
右外连接,right outer join右边的是主表
3、左外和右外交换两个表的顺序,可以实现同样的效果
此外这个outer是可以省略的,但我个人觉得写出来会比较好
eg:
多表连接练习案例:
六、联合查询
将多条查询语句的结果合并成一个结果,应用场景为查询的结果来自多个表,且多个表没有直接的连接关系,但查询的信息一致的时候。另外联合查询在SQL注入中也常常使用
但是联合查询也不是没有要求的,联合查询的每一条语句查询出的列数必须是一样的,不然查出来的东西就不是一张表格了嘛。此外联合查询如果出现了重复信息默认会去重,如果不想去重需要加关键字ALL