在学习之前,我们需要了解数据库到底是做什么的?
数据库定义
数据库是用于持久化存储数据的软件,在需要时可以增删改查。数据库本质上是把程序中的数据保存到计算机硬盘中。
数据库分类
数据库产品非常多,常见的有两类:
(1)关系型数据库:行与列的格式,例如Excel表格的形式。
常见的是SQLite、MySQL、SQLServer、Oracle、DB2…
(2)非关系型数据库:使用JSON格式。
常见的有MongoDB。
SQLite数据库
嵌入式最常用的数据库是SQLite,SQLite是一种轻量级的关系型数据库,本体只有几兆大小。SQLite常见的数据操作都有,但是由于本体较小,相比其它数据库:
(1)语法结构不严格
(2)在很多系统或软件框架中自带
(3)主要进行本体数据库存储和管理,不太擅长高并发的服务器系统
本次学习主要使用两个文件:
(1)SQLiteSpy.exe
这是一个免安装直接打开就能使用的SQLite操作软件,内置了SQLite数据库。
(2)scott.db
.db或.db3格式是SQLite数据库的格式,scott.db内部存储的是本次的学习数据。
SQLite中,.db文件是数据库文件,这个文件可以认为等效于.xlsx表格文件。在Excel中,点击下方的标签,切换一个又一个的表(Sheet),在数据库中使用(Table)
来表示相同含义。
注意:scott.db文件只是一个数据库文件,里面的数据项比较经典,用户也可以使用自己的数据库文件。
打开 SQLiteSpy数据库操作软件
SQLiteSpy下载完成后, 使用SQLiteSpy打开学习数据的操作步骤如下:
1、双击打开SQLiteSpy软件
2、在软件中点击File,点击Open Database
3、在弹出的窗口中选中scott.db就可也以打开学习数据了
SQL语言
为了统一不同的数据库产品的操作方式,IBM公司在上世纪70年代发明了SQL语言,SQL语言已经成为关系型数据库的通用操作语言。
SQL语言分为三类:
(1)数据操作语言 DML
[1] 数据查询语言 DQL
通过各种条件的限制,筛选和整理出需要数据。
[2] 更新操作
包括对数据的增删改
(2)数据定义语言 DDL
定义数据库格式,常见于设计数据库表,一般由软件架构师负责。
(3)数据控制语言 DCL
用于操作数据库账户的控制权限,一般由数据库管理员负责。
我们今天所学的就是数据查询语言 DQL!!!
1、简单查询
简单查询的结果包含所有的行(记录),依次展示每条数据,但是可以控制显示哪些列(字段)。
SELECT * –选中那几列
FROM emp; –从emp表中查询数据
[]表示可选填内容
|表示或者
*表示全查
DISTINCT表示去掉重复行
在SQLiteSpy中填写上述语句,点击键盘F9或依次鼠标点击Execute—Execute SQL
例子:查询所有雇员的编号(empno)、姓名(ename)、职位(job)、基本工资(sal)。
SELECT empno,ename,job,sal
FROM emp;
2、限定查询
定义:在简单查询的基础上限制结果的行数,就是限定查询。限定查询主要通过WHERE子句完成。
分类:
支持六种运算:关系运算、取值范围运算、基数范围运算、模糊查询、空判断、逻辑运算
2.1. 关系运算
关系运算是最简单的运算符号,包括:
< 小于
> 大于
>= 大于等于
<= 小于等于
!= 不等于
== = 等于
例子:查询薪金在2000以上的雇员信息。
SELECT * FROM emp WHERE sal>2000;
2.2 取值范围运算
使用BETWEEN a AND b表示一个[a,b]的闭区间。
例子:查询在1981年雇佣的雇员信息。
分析:雇佣日期在1981年1月1日到1981年12月31日。
时间和日期一定要按照标准格式的字符串编写。
SELECT *
FROM emp
WHERE hiredate BETWEEN ‘1981-01-01’ AND ‘1981-12-31’;
2.3 基数范围运算
数据在几个可选的选中存在,使用IN操作完成。
例子:查询出雇员编号不为7369、7566、7839和8899(不存在)的雇员。
– NOT是取反
SELECT *
FROM emp
WHERE empno NOT IN (7369,7566,7839,8899);
IN不能与NULL一起使用,一起使用没有任何效果。
2.4 模糊查询
模糊查询可以只通过部分内容查询所完成的数据,使用LIKE配合两个标记符:
_ 匹配任意一个字符
% 匹配任意多个(0,1,…n)字符
例子:查询所有姓名以字母A开头的雇员信息。
SELECT *
FROM emp
WHERE ename LIKE ‘A%’;
2.5. 空判断
NULL是一种特殊的数据状态,表示无内容。
例子:查询不领取佣金的雇员信息。
– 错误的写法:NULL不能使用关系运算符判断
SELECT *
FROM emp
WHERE comm=NULL;
使用IS NULL来判断一个数据是否为空。
使用IS NOT NULL或者NOT IS NULL判断非空。
– 上面的例子的正确写法
SELECT *
FROM emp
WHERE comm IS NULL;
例子:查询领取佣金的雇员信息。
SELECT *
FROM emp
WHERE comm IS NOT NULL;
或者
SELECT *
FROM emp
WHERE NOT comm IS NULL;
2.6. 逻辑运算
与 AND:所有条件都满足,结果才满足。
或 OR:所有的条件满足一个,结果就满足。
非 NOT:反转结果
例子:查询出工资高于1300的销售人员信息。
分析:要同时满足两个筛选条件 sal>1300 job=‘SALESMAN’
程序:SELECT *
FROM emp
WHERE sal>1300 AND job=‘SALESMAN’;
3、查询排序
查询排序,可以制定一列或多列按照升序或降序的顺序排序。
使用ORDER BY子句配合两种排序方式的关键字:
ASC 升序
DESC 降序
例子:
查询所有雇员的信息,按照工资降序排布。如果工资相同,
则按照雇佣日期从早到晚排布。
SELECT *
FROM emp
ORDER BY sal DESC,hiredate ASC;
4、常用函数
函数是一组完成预设的特定功能的代码。使用时只需要调用即可。函数调用主要包含三部分内容:
(1)输入参数
类似于烹饪的原材料,表示处理之前的源数据。
(2)函数名称
类似于烹饪的方式,表示处理数据的方式。
(3)返回值
类似于烹饪的成品,表示数据处理的结果。
4.1 时间和处理函数
函数名称:
DATE 处理日期
TIME 处理时间
DATETIME 处理日期和时间
输入参数:
参数1:‘now’
参数2:‘localtime’,此参数可以省略。
返回值:
当前时区的当前时间或日期,如果省略参数2,返回格林威治时间。
例子:分别显示当前的格林威治时间日期和东八区时间日期。
SELECT DATETIME(‘now’),DATETIME(‘now’,‘localtime’);
4.2 时间日期格式化函数
函数名称:
STRFTIME 把某个时间日期转换成自定格式,通常用于提取部分数据
输入参数:
参数1:时间和日期的格式
参数2:要处理的原始时间或日期
返回值:
按照参数1的格式处理后的参数2的数据,需要注意返回的类型是字符串类型。
例子:查询在1981年雇佣的雇员信息。
SELECT *
FROM emp
WHERE STRFTIME(‘%Y’,hiredate)=‘1981’;
4.3 空值函数
例子:查询所有雇员的姓名和月综合收入(薪金+佣金)
– 错误的做法,NULL参与数学计算时,会把结果同化为NULL
SELECT ename,sal+comm income FROM emp;
可以使用空值函数处理上述问题。
函数名称:IFNULL
输入参数:
参数1:可能为空的列名
参数2:如果参数1的数值为NULL,则替换的数值。
返回值:
如果参数1为NULL,则返回值参数2;
如果参数1不为NULL,则返回值参数1。
– 对上面的例子使用IFNULL函数处理
SELECT ename,sal+IFNULL(comm,0) income FROM emp;
4.4 统计函数
常用的统计函数有五个:
COUNT 计数
AVG 平均值
SUM 求和
MAX 最大值
MIN 最小值
例子:求出公司中人数、支付的总工资、平均工资、最高工资和最低工资。
SELECT COUNT(*),SUM(sal),AVG(sal),MAX(sal),MIN(sal) FROM emp;
5 分页查询
当查询结果返回的数据量很大时,可以分多页展示数据。
分页查询使用LIMIT和OFFSET子句实现。
因为分页查询并不是特别常用,因此通常不把这两个子句加入标准子句的格式中。
但是分页查询子句都是最后执行,因此所有分页查询的操作可以先不考虑分页查询,
最后再加上分页的语句。
LIMIT 可以控制结果显示的数量,LIMIT可以单独使用,也可以与OFFSET一起使用。
OFFSET 必须与LIMIT同时使用,表示跳过前几条数据。
例子:
查询默认排序中前五个雇员的信息。
SELECT * FROM emp LIMIT 5;
例子:
查询公司薪金第四名到第八名的雇员信息。
SELECT * FROM emp ORDER BY sal DESC LIMIT 5 OFFSET 3;
分页查询公式:
设每页显示的数量为n,当前页码为m,则分页查询的公式为:
SELECT * FROM 表名 LIMIT n OFFSET (m-1)*n;
例子:
每页显示6条数据,查询第二页的内容。
分析:n=6,m=2,带入公式
SELECT * FROM emp LIMIT 6 OFFSET 6;
6 多表查询
之前的所有查询都是单表查询,因为FROM子句中只有一个表。实际上FROM子句后面跟的表名可以有多个。同时查询多张表,这种查询就叫多表查询。
例子:分别统计emp表和dept表的数据量。
– 统计emp表数据量
SELECT COUNT() FROM emp;
– 统计dept表数据量
SELECT COUNT() FROM dept;
– 同时统计emp表与dept表的数据量
SELECT COUNT(*) FROM emp,dept;
可以看到同时统计两张表的数据量,结果是两张表的数据量的乘积。
直接查询两个的内容。
SELECT * FROM emp,dept;
通过结果可以看到每个人都产生了一些冗余数据,这种现象被称为“笛卡尔积”。
消除“笛卡尔积”的方法就是消除冗余数据,需要找到两个表之间的关系。这种关系通常是通过关联字段(列)表示。
对于emp表与dept表而言,其关联字段为deptno,只有两个表的deptno相同时,
结合的数据才是有效。
–消除笛卡尔积
SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno;
例子:查询所有雇员的姓名和位置。
SELECT ename,loc
FROM emp,dept
WHERE emp.deptno=dept.deptno;
课堂练习:
查询部门20的雇员的姓名和部门名称。
SELECT ename,dname
FROM emp,dept
WHERE emp.deptno=dept.deptno AND dept.deptno=20;
特殊的多表查询例子:
查询所有雇员的姓名、职位和工资等级。
分析:
emp表与salgrade表都需要使用,但是无法建立等式关系,可以通过BETWEEN AND建立区间关系,让每个雇员的薪金位于每个等级下限与上限之间。
SELECT ename,job,grade
FROM emp,salgrade
WHERE sal BETWEEN losal AND hisal;