数据库
SQL概述
SQL一般发音为 sequel,SQL 的全称 Structured Query Language),SQL 用来和数据库打交道,完成和数据库的通信,SQL是一套标准。但是每一个数据库都有自己的特性别的数据库没有,当使用这个数据库特性相关的功能,这时 SQL语句可能就不是标准了.(90%以上的 SQL 都是通用的)
什么是SQL
SQL(Structured Query Language)是结构化查询语言的简称,它是一种数据库查询和程序设计语言,同时也是目前使用最广泛的关系型数据库操作语言。在数据库管理系统中,使用SQL语言来实现数据的存取、查询、更新等功能。SQL是一种非过程化语言,只需要提出“做什么”,而不需要指明“怎么做”。
SQL是一套标准,程序员主要学习的就是SQL语句
什么是数据库
数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不再仅仅是存储和管理数据,而转变成用户所需要的各种数据管理的方式。数据库(Database)是按照数据结构来组织、存储和管理数据的仓库
什么是数据库管理系统(DBMS)
用来管理数据库的计算机系统称为数据库管理系统(Database Management System,DBMS)
-
常见的数据库管理系统:
- MySQL
- Oracle
- MS
- SQLServer
- DB2
- ...
MySQL的常用命令
-
启动MySQL服务
- net stop mysql:停止mysql服务(windows)
- net start mysql:启动mysql服务(windows)
-
登录\退出MySQL
- mysql -u[username] -p [password]:登录MySQL
- exit:退出MySQL
-
数据库基本命令
- show databases:查询所有数据库
- use [database]:使用数据库
- show tables:查看数据库下所有表
- create database [databasename]:创建数据库
- source [SqlFilePath]:导入数据库脚本语句(!!!注意路径中不能有中文)
- desc [tablename]:不看数据库中的数据,只看表结构
- select version():查看数据库版本
- select database():查看当前使用的数据库
数据库中的最基本的单元
数据库中最基本的单元是 表(table),因为表比较直观。
-
任何一张表都有行和列
- 行(row):被称为数据/记录。
- 列(column):被称为字段
-
了解一下
-
每个字段都有:字段名、数据库类型、约束等属性
-
字段名可以理解,是一个普通的名字,见名知意就行。
-
数据类型: 字符串,数字,日期等,后期讲。
-
约束:
- 约束也有很多,其中一个叫做唯一性约束这种约束添加之后,该字段中的数据不能重复
-
SQL的分类
SQL语句有很多,最好分门别类,这样更容易记忆
-
SQL的类型
-
DQL: 数据查询语言 (凡是带有select关键字的都是查询语句)select...
-
DML:数据操作语言(凡是对表当中的数据进行增删改的都是DML)
-
DDL:数据定义语言凡是带有create、 drop、 alter的都是DDL。DDL主要操作的是表的结构。
不是表中的数据
create: 新建,等同于增
drop: 删除
alter: 修改
这个增删改和DMM不同,这个主要是对表结构进行操作。 -
TCL:事务控制语言
-
DCL:数据库控制语言。例如:授权grant、撤销权限revoke..
-
MySQL查询语句(DQL)
简单查询
-
查询字段
- select [columnName] from [tableName]:查询一个字段
- select [columnName1],[columnName2]... from [tableName]:查询多个字段(用逗号隔开字段)
- select * from [tableName]:查询所有字段(不推荐!!!,效率低)
-
给查询字段起别名
-
select [columnName] as [nickname] from [tableName]:使用 as 给字段起别名。
(!!!注意:as 只是给字段名起个别名显示,原表字段该叫啥还是叫啥。select语句永远只能查询不能修改)
-
-
列(column)参与数学运算
- select [column*12] from [tablename]:结论字段是可以使用数学表达式
条件查询
-
条件查询需要用到where语句,where必须放到from语句表的后面
-
支持如下运算符
运算符 说明 = 等于 <>或!= 不等于 < 小于 <= 小于等于 > 大于 >= 大于等于 between … and …. 两个值之间,等同于 >= and <= is null 为null(is not null 不为空) and 并且 or 或者 In 包含,相当于多个or(not in不在这个范围中) Not not可以取非,主要用在is 或in中 like like称为模糊查询,支持%或下划线匹配
-
where
-
select [columnName1],[columnName2],[columnName3]...from [tableName] where [columnName1] = [prerequisite]:使用where字段给查询添加条件
-
and
-
select [columnName1],[columnName2],[columnName3]...from [tableName] where [columnName1] = [prerequisite] and [columnName2] = [prerequisite]:where语句给字段添加条件,还可以加上and(并且)语句增加条件
(!!!注意在数据库中不能使用等号衡量,需要使用is null 因为数据库中的nu11代表什么也没有,它不是一个值,所以不能使用等号衡量。)
-
-
or
- select [columnName1],[columnName2],[columnName3]...from [tableName] where [columnName1] = [prerequisite] or [columnName2] = [prerequisite],or [columnName3] = [prerequisite]:where语句给字段添加条件,还可以加上or(或者)语句增加条件
-
in 包含,相当于多个 or(not in 不在这个范围中)
-
not not 可以取非,主要用在 is 或 in 中
-
like like 称为模糊查询,支持8或下划线匹配
- select [columnName1],[columnName2],[columnName3]... from [tableName] like '%prerequisite%'
-
&匹配任意个字符下划线,一个下划线只匹配一个字符
-
排序order by
- select [columnName1],[columnName2],[columnName3]... from [tableName] order by [column1]:给[column1]进行排序(默认是升序)
- select [columnName1],[columnName2],[columnName3]... from [tableName] order by [column1] desc:给[column1]进行排序(desc:指定为降序)
- select [columnName1],[columnName2],[columnName3]... from [tableName] order by [column1] aesc:给[column1]进行排序(aesc:指定为升序)
数据处理函数\单行处理函数
-
-
lower:转小写
- select lower([columnName]) from [tableName]:(14个输入,最后还是14个输出。这是单行处理函数的特点。)
-
upper:转大写
- select upper([columnName]) from [tableName]
-
substr:取字符串(substr( 被截取的字符串,起始下标,截取的长度))
- select substr([columnName],1,1) from [tableName];
-
lengtn:取长度
- select lengtn([columnName]) from [tableName];
-
trim:去除空格
- select [columnName] from [tableName]where [columnName]= trim(' [prerequisite]')
-
str_to_date:将字符串转为日期
-
date_format:格式化日期
-
format:设置千分位
-
round:四舍五入
-
rand():生成随机数
-
ifnull:将null转为一个具体的值
-
分组函数(多行处理函数)
多行处理函数的特点: 输入多行,最终输出一行
-
-
count:计数
- select count([column]) from [tableName]
-
sunm:求和
- select sunm([column]) from [tableName]
-
avg:求平均值
- select avg([column]) from [tableName]
-
max:求最大值
- select max([column]) from [tableName]
-
min:求最小
- select min([column]) from [tableName]
-
-
-
分组函数在使用的时候必须先进行分组,然后才能用。如果你没有对数据进行分组,整张表默认为一组。
-
分组函数会自动或略null
-
分组函数中count(*)和count(具体字段) 有什么区别?
- count(具体字段):表示统计该字段下不为null元素的总数
- count(*):表示统计当表中的总行数(只要有一行数据count则++)
-
分组查询(group by)
-
在实际的应用中,可能有这样的需求,需要先进行分组,然后对每一组的数据进行操作。这个时候我们需要使用分组查询,怎么进行分组查询呢 ?
-
select ... from ... where ... group by ... order by ...需要记忆。以上关键字的顺序不能颠倒,执行顺序是什么
- from
- where
- group by
- order by
为什么分组函数不能直接使用在where后面?
-
[ ]
select ename,sal from emp where sal > min(sal)//报错 //因为分组函数在使用的时候必须先分组之后才能使用。 where执行的时候,还没有分组。所以where后面不能出现分组函数。 select sum(sal) from emp ; //这个没有分组,为啥sum 函数可以用呢? //因为select在qroup by之后执行。
-
列子:
-
找出每个工作岗位的工资总和?
<!--实现思路:按照工作岗位分组,然后对工资求和--> select job,sum(sal) from emp group by job;
重点总结:
- 在一条select语句当中,如果有group by语句的话select后面只能跟: 参加分组的字段,以及分组函数。其它的一律不能跟。
-
-
having:对于分完组之后的数据再次进行过滤
select [columnname1],max([columnname2]) from [tableName] group by [columnname1] having max([columnname2]) > 3000; -
distinct:取出重复字段(!!!distinct只能出现字段的最前方)
<!--distinct只能出现字段的最前方--> select distinct [columnname] from [tablename]
连接查询
-
什么是连接查询?
- 从一张表中单独查询,称为单表查询。
- table1和table2表联合起来一起查询数据,比如从table1中取出员工名字,从table2中取出部门名字。这种跨表查询,多表联合起来一起查询数据被称为连接查询
-
连接查询的分类?
- SQL92:1992年的时候出现的语法
- SQL99:1999年的时候出现的语法
-
根据连接的方式分类
-
内连接
- 等值连接
- 非等值连接
- 自连接
-
外连接
- 左外连接
- 右外连接
-
全连接
-
笛卡儿积
-
当两张表进行连接查询时,没有任何条件的限制会发生什么现象?
-
案例:查询每个员工所在部门名称
-
两张表连接没有任何限制
select * from emp,dept; <!--这个时候我们查询出来了许多不该出现的数据--> 56 rows in set (0.00 sec) 14 * 4 = 56当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是两张表条数的乘积,这种现象被称为: 笛卡尔积现象。(笛卡尔发现的,这是一个数学现象。)
-
怎么避免笛卡尔积现象?
-
连接时加条件,满足这个条件的记录被筛选出来!
select * from emp,dept where emp.deptno = dept.deptno; 14 rows in set (0.00 sec) -
思考:
- 最终查询的结果条数是14条,但是匹配的过程中,匹配的次数减少了吗?还是56次,只不过进行了四选一。次数没有减少。
-
注意:
- 通过笛卡尔积现象得出,表的连接次数越多效率越低,尽量避免表的连接次数。
-
-
内连接
等值连接
-
案例:查询每个员工所在部门名称,显示员工名和部门名?
-
SQL92语法:
select e.ename,d.dname from emp as e ,dept as d where e.deptno = d.deptno;缺点:结构不清晰,表的连接条件,和后期进一步筛选的条件,都放到了where后面
-
SQL99语法:
select e.ename,d.dname from emp as e join dept as d on e.deptno = d.deptno;优点: 表连接的条件是独立的,连接之后,如果还需要进一步筛选,再往后继续添加where
-
非等值连接
-
案例:找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级?
select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal条件不是一个等量关系,称为非等值连接
自连接
-
案例:查询员工的上级领导,要求显示员工名和对应的领导名?
select a.ename as '员工名',b.ename as '领导名' from emp a join emp b on a.MGR= b.EMPNO;技巧:一张表看成两张表
-
以上就是内连接的自链接
外连接
内连接特点:完全能匹配上这个条件的数据库给查询出来。两张表平等没有主次关系
-
外连接
select e.ename,d.dname from emp e right join dept d on e.deptno = d.deptno;- right(右外连接)代表什么:表示将join关键字右边的这张表看成主表,主要是为了将
这张表的数据全部查询出来,捎带着关联查询左边的表。产生了主次关系。在外连接当中,两张表连接, - left(左外连接)
- right(右外连接)代表什么:表示将join关键字右边的这张表看成主表,主要是为了将
子查询
-
什么是子查询?
select语句中嵌套select语句,被嵌套的select语句被称为子查询
-
子查询都可以出现在哪呢?
- select...(select)
- from...(select)
- where...(select)
-
where子语句中的子查询
-
案例:找出比最低工资高的员工姓名和工资 ?
-
实现思路:
-
查询最低工资
select min(sal) from emp; -
找出大于800的
select ename.sal from emp where sal > 800 -
合并
select ename,sal from emp where sal > (select min(sal) from emp);
-
-
-
from子句中的子查询
!!!from后面的子查询,可以将子查询的查询结果当做一张临时表。注意:(技巧)
-
案例:找出每个岗位的平均工资的薪资等级
-
第一步:找出每个岗位的平均工资(按照岗位分组求平均值)
select job,avg(sal) from emp group by job; -
第二步:克服心理障碍,把以上的查询结果就当做一张真实存在的表t。
(薪资等级表 s)select * from salarade: st表和s表进行表连接。 条件: t表avg(sal) between s.losal and s.hisal;
select from t.* join salarade s on t.avg(sal) between s.losal and s.hisal; -
第三部:合并
select t.*,s.GRADE from (select job,avg(sal) as salavg from emp group by job) as t join salgrade s on t.salavg between s.losal and s.hisal;
-
-
select子句中的子查询
- 案例找出每个员工的部门名称,要求显示员工名、部门名
-
union(合并查询结果集)