个人笔记之MySQL查询语句
1.DQL
DQL(database quary language)是对数据库查询语句的统称,单独将它拿出来作为MySQL中的一个分支也是说明了它的重要性。不只是在MySQL中,其他数据库语言例如SQLserver和Oracle中查询语句也是比较重要的组成部分,因为我们日常使用数据库时一般都是变着花样来查询其中的数据,其中涉及到单表查询和多表查询,内容非常丰富。
但是也不必害怕它,其实所有查询语句都要遵循固定的语法,多表查询语句可以从单表查询语句上延伸得到。
2.单表查询
优点:查询速度快,风险低(慢就怪笛卡尔积)
基础语法:select 【要查询的字段名】 from 【要查询的表】where 【过滤条件】;
SQL语言很好看懂,格式也比较固定,从某某表中查询满足某某条件的某某数据。
首先我们有两张表,emp表存储员工信息,dept表存储部门信息
拿到一张表,首先关注一下字段名,大致了解各种字段名存储的是什么信息以及大概存储的是什么格式的数据,
比如emp表中很明显存储的是员工的信息,有empno,存储员工编号,简称工号;
有ename,存储员工姓名,job存储工作岗位,sal存储工资等等…
而重点是emp表和dept表中都有deptno(部门编号)这个字段,其实这里是把dept表的主键放在emp表中当做外键,以达到连接两张表的目的。
例:
--这是SQL中的注释方式
--第一句,从emp表中查询所有数据,此时会显示存在于emp表中的所有的数据
select * from emp;
--第二句,搜索emp表中所有的name属性,此时返回name列的值
select name from emp;
--第三句,搜索emp表中名字带有字母"O"的员工的名字
select name from emp where name like '%O%';
--第四句,查询emp表中工资大于2000的员工姓名和工资
select name,sal from emp where sal>2000;
--第五句,查询emp表中工资大于2000的员工信息,按照工资多少降序排序
select * from emp where sal>2000 order by sal desc;
--第六句,查询员工的年薪
select sal*12 from emp ;
--第七句,查询员工的平均工资
select avg(sal) from emp;
--第八句,查询每个部门员工的平均工资
select avg(sal) from emp group by deptno ;
--第九句,查询各部门员工工资的总和
select deptno,sum(sal) from emp group by deptno;
--第十句,查询各部门工资大于本部门平均工资的员工信息
select * from emp e1 where sal>(select avg(sal) from emp e2 group by deptno having e1.deptno=e2.deptno );
(1)select * from emp;
“*“在数据库语言中可以指代所有数据,“_” 表示一个任意字符,”%” 表示任意个任意字符, _ 以及 % 通常在模糊查询中使用。
(2)select name from emp;
name在这里是表中的一个字段名,也是需要查询的对象,所以从这里我们可以看出,要想使用这张表我们首先需要知道这张表的一些信息才能开始使用,如果你要查询的字段在表中找不到的话会报错。可以同时查询多个对象,用逗号隔开。
(3)select name from emp where name like ‘%O%’;
where限定字表示过滤器,其后跟着的为过滤条件,在筛选满足特定条件的数据时将筛选条件写在where后面起过滤作用。
like是模糊查询的关键字,通过 _ 和 % 符号控制需要查询的数据的格式,在表中筛选出与目标字段格式匹配的数据。
(4)select name,sal from emp where sal>2000;
对整型数据进行筛选时,可以使用 > , < , = , != 符号进行比较,但对非整型数据比较时只能使用 = 或 != 直接进行比较。
in(a,b)表示在存在与in后列表中列举的元素(可用于非整型数据)
between a and b 表示数值大小在 a 和 b 之间的数据。
a>all(*)表示a 大于all后括号内所有数据,即为大于最大数
a<all(*)表示a小于all后括号内所有数据,即为小于最小数
a>any/some (*)表示a满足大于其后括号内任何数字即可,即为大于最小值
a<any/some (*)表示a满足小于其后括号内任何数字即可,即为小于最大值
(5)select * from emp where sal>2000 order by sal desc;
order by 排序,如果后面不跟关键字则默认升序 DESC, 降序是 ASC
group by 表示分组,根据字段名把同种类型的数据分组运算输出
使用逗号可以指定多个查询对象,
使用and关键字可以连接筛选条件,当前后条件均满足时才能输出,机制类似短路与
使用or关键字可以连接筛选条件,只要满足前后条件中的任意条件即可,机制类似短路或
(6)select sal*12 from emp ;
dual是SQL语句中虚表的标识符,表示一张不存在的表,与之对应的是伪列的概念,可以输出某些数据或者完成某些运算
指定的查询目标可以使用函数或者通过运算来改变输出的最终结果,此处输出的值是在sal的基础上乘以12以后的值
(7)select avg(sal) from emp;
avg()求平均数函数
sum()求和函数
max()输出最大值
min()输出最小值
count()计数
concat(a,b)拼接方法,将a和b两个字段拼接成一个字段 ’ab‘ 输出
distinct 关键字,跟在字段名前面用于去重,语法:select distinct deptno from emp;此时将不会看到重复的部门信息。
select * from emp limit 0,4 ;–分页常用,前面的参数表示起始查询位置,逗号后面的参数表示每页现实的数据条数。若直接使用 limit x ;则表示显示前x条数据。
(8)select avg(sal) from emp group by deptno ;
求和函数配合分组,能输出每一组工资的和
(9)select deptno,sum(sal) from emp group by deptno;
分组时能看看分组名
(10)select * from emp e1 where sal>(select avg(sal) from emp e2 group by deptno having e1.deptno=e2.deptno );
将查询结果作为判断条件筛选输出,此处并不是连表查询,而是将单表查询的结果作为筛选条件进行查询,不涉及笛卡尔积所以效率尚可,也比较常见。
3.连表查询
将两张以上的表关联起来查询,以得到无法从一张表直接查询到的结果。
例:
select ename,job,dname from emp,dept WHERE emp.deptno=dept.deptno;
解释:在emp和dept表中查询员工的姓名,职位和部门名称,但是此时emp表中没有部门名称,只能从dept表中找到,连表查询时会将两张表相乘得到一个笛卡尔积(建议百度),所以要在where后加上筛选条件保证得到的信息是想要的。
1.笛卡尔积
而如果想熟练使用多表查询的话,首先要了解 笛卡尔积 的概念,这里简单解释下笛卡尔积就是两张表 相乘 得到的结果,举例如下:
select * from emp,dept; —>这句的意思是:从emp表和dept表查询所有信息,具体输出结果如下:
这里显示查询出了56条数据,因为emp表中有14条数据,dept表中有4条数据,而笛卡尔积显示的结果就为56条数据。
2. 92,99语法
简单来说就是92年的时候人家出了一套规范,规定一些sql的写法,但是到了99年又出了一套新的语法规范,这两种语法都能用,但是不能混用。有些人喜欢92写法,有些人喜欢99写法,所以工作中经常会碰到,到时候能认出来就好了。
92:
就是先查出笛卡尔积,然后再用过滤条件筛选得到想要的结果。(从今天起用99了)
例:
select * from emp,dept;--笛卡尔积
select * from emp,dept where emp.deptno=dept.deptno ;--将两张表通过部门编号关联查询
99:
cross join,nature join , join using ,inner join on , left join , right join,full join
加入新的关键字时语句更简洁,同时提高可读性。
例:
select * from emp cross join dept;--笛卡尔积
select * from emp nature join dept;--将两张表通过相同字段(自动找到相同字段名)关联查询
select * from emp join dept using(deptno); --将两张表通过部门编号(指定同名字段)关联查询
select * from emp inner join dept on emp.deptno=dept.deptno;--将两张表通过两个指定字段比较连接
select * from emp left join dept on emp.deptno = dept.deptno;--将两张表以左表为主导连接,左表保留所有数据,右表若无匹配字段则显示为空
select * from emp right join dept on emp.deptno = dept.deptno;--将两张表以右表为主导连接,右表保留所有数据,左表若无匹配字段则显示为空
select * from emp full join dept;--显示两表关联查询的数据,保留两表全部信息
union将两张表的查询结果合并,去重:
select * from emp union
select * from emp where deptno in(10,20);
union all 将两张表的查询结果合并,不去重
select * from emp union all
select * from emp where deptno in(10,20);