一小时学会SQL

本篇目的是为了对数据库操作不熟悉的同学,在较短时间内掌握数据库的基本操作,增删改查等操作,适合对数据库有一定了解的同学

概述

有关数据库概述,数据库管理系统的基本概念介绍就不重复了,我们只需要知道 SQL是关系数据库语言的国际标准,所以只要学会了 SQL 的操作,其他任何数据库如 MySql Oracle 等都可以进行快速上手,我们本篇采用MySQL 数据库进行演示

SQL 分类

DDL操作

  • Data Definition Language:数据定义语言,用来定义数据库对象,库 表 列
  • 使用关键字:CREATE ALERT DROP

操作数据库

  • 创建
    • create database name1
    • create database name1 character set gbk
  • 查询
    • show database ———————– 查询数据库服务器中的所有数据库
    • show create database mydb1 ——— 查询mydb1 数据库的定义信息
  • 修改
    • alert database mydb1 character set utf8 ——————- 查看数据库 并修改字符集为 utf8
  • 删除
    • drop database mydb1 ————————————— 删除数据库

DML操作

  • Data Manipulation Language :数据操作语言,用来定义数据库的记录,对表中的数据进行增、删、改操作
  • insert
  • update
  • delete

插入操作 insert

  • 语法:insert into 表名 (列名1,…) values(values1,…)
  • 列名与 值的 类型,个数,顺序都要一一对应
  • 如果要插入空值,使用 null
  • 插入的日期和字符要一样,要使用引号括起来

修改操作 update

  • 语法:update 表名 set 列名1 = 值1,… where 插入的位置

删除操作 delete

  • 语法: delete from 表名 where 条件
  • 还可以使用 truncate 来进行操作,truncate 是把表直接删除掉,然后再重新创建一个同样的新表,删除的数据不能找回,执行速度比 delete 好,delete 删除表中的数据,表的结构还在,数据还可以找回

DQL操作

  • Data Query Language : 数据查询语言,用来查询数据,这是我们操作数据的重点
  • 语法:
     select selection_list    / 要查询的列名
     from table_list           / 要查询的表名
     where condition       / 要查询的条件
     group by    grouping_colunmns      / 对查询的条件进行分组
     having     condition   / 分组后的行条件
     order by sorting_colunmns   / 对结果进行排序
     limit offset_start,row_count   / 对结果进行限定
  • 下面我们来创建3张表来说明DQL

学生表:stu

字段 类型 说明
sid char(6) 学生学号
sname varchar(50) 学生姓名
age int 学生年龄
gender varchar(50) 学生性别
.sql
CREATE TABLE stu(sid char(6), sanme varchar(50),age int,gender varchar(50));

INSERT INTO stu VALUES('S_1001', 'liuYi', 35, 'male');
INSERT INTO stu VALUES('S_1002', 'chenEr', 15, 'female');
INSERT INTO stu VALUES('S_1003', 'zhangSan', 95, 'male');
INSERT INTO stu VALUES('S_1004', 'liSi', 65, 'female');
INSERT INTO stu VALUES('S_1005', 'wangWu', 55, 'male');
INSERT INTO stu VALUES('S_1006', 'zhaoLiu', 75, 'female');
INSERT INTO stu VALUES('S_1007', 'sunQi', 25, 'male');
INSERT INTO stu VALUES('S_1008', 'zhouBa', 45, 'female');
INSERT INTO stu VALUES('S_1009', 'wuJiu', 85, 'male');
INSERT INTO stu VALUES('S_1010', 'zhengShi', 5, 'female');
INSERT INTO stu VALUES('S_1011', 'xxx', NULL, NULL);

雇员表:emp

字段 类型 说明
empno int 员工编号
ename varchar(50) 员工姓名
job varchar(50) 员工工作
mgr int 领导编号
hiredate date 入职日期
sal decimal(7,2) 月薪
comm decimal(7,2) 奖金
deptno int 部门编号
.sql
create table emp(empno int,ename varchar(50),job varchar(50),mgr int,hiredate date,sal decimal(7,2),,comm decimal(7,2),deptno int);

INSERT INTO emp values(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO emp values(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
INSERT INTO emp values(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
INSERT INTO emp values(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);
INSERT INTO emp values(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);
INSERT INTO emp values(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30);
INSERT INTO emp values(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10);
INSERT INTO emp values(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,NULL,20);
INSERT INTO emp values(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
INSERT INTO emp values(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30);
INSERT INTO emp values(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20);
INSERT INTO emp values(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30);
INSERT INTO emp values(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20);
INSERT INTO emp values(7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10);

部门表:dept

字段 类型 说明
deptno int 部门编号
dname varchar(50) 部门名称
loc varchar(50) 部门地址
.sql
create tabal dept(deptno int,dname varchar(50),loc varchar(50));

INSERT INTO dept values(10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO dept values(20, 'RESEARCH', 'DALLAS');
INSERT INTO dept values(30, 'SALES', 'CHICAGO');
INSERT INTO dept values(40, 'OPERATIONS', 'BOSTON');

根据上面3张表,我们对这3张表进行如下操作

1 基础查询

  • 查询所有列:select * from stu
  • 查询指定列:select sid,sname,age from stu

2 条件查询

  • 就是在查询时给出 where 字句,where 字句中使用如下的运算符以及关键字
    • =、!=、<>、 <、<=、>、>=
    • between… and
    • in(set)
    • is null
    • and
    • or
    • not
  • 查询性别为女,年龄小于50的记录:select * from stu where gender = 'female' and age < 50;
  • 查询学号为 S_1001,或者姓名为 liSi 的记录:select * from stu where sid = 'S_1001' or sname = 'liSi'
  • 查询学号为 S_1001,S_1002,S1003 的记录:`select * from stu where sid in('S_1001','S_1002','S_1003');
  • 查询学号不是 S_1001,S_1002,S1003 的记录:
    • select * from stu where sid NOT IN('S_1001','S_1002','S_1003');
  • 查询年龄为null的记录:SELECT * FROM stu WHERE age IS NULL;
  • 查询年龄在20到40之间的学生记录:
    *select * from stu where age between 20 and 40
    *select * from stu where age >=20 and age <=40
  • 查询性别非男的学生记录:
    • select * from stu where gender !='male'
    • select * from stu where gender <> 'male'
    • select * from stu where not gender ='male'
  • 查询姓名不为 null 的学生记录
    • select * from stu where sname is not NULL
    • select * from stu where not sname is NULL

3 模糊查询

  • 如果我们要查询的字段中只包含某个字段,我们使用 模糊查询,使用关键字 LIKE ,

    • _ :代表任意一个字符
    • %:代表任何长度的 字符
  • 查询姓名由 5 个字母构成的 学生记录:select * from stu where sname like '_____'

  • 查询姓名由5个字母构成,并且第5个字母为“i”的学生记录
    • select * from stu where sname like '____i';
  • 查询姓名以“z”开头的学生记录
    • select * from stu where sname like 'z%'
  • 查询姓名中包含“a”字母的学生记录
    • select * from stu where sname like '%a%'

4 字段控制查询

  • 重复记录,我们查询的结果集中可能有重复的数据,这时候使用 distinct 关键字来处理:select distinct sal from emp

  • 字段为空,查看 emp 表中的 月薪和 奖金之和,因为 sal 和 comm 都是数值类型,可以直接进行 加运算,反之,会出错

    • select * ,sal+comm from emp
    • select *,sal+ IFNULL(comm,0) from emp
    • 如果我们要查询的 列 中 记录有 NULL ,那么使用 IFNULL 函数,把 NUL 转换为 默认数值,上面默认 为 0
  • 给列名添加 别名 : 我们可以给查询出来的列重新起名,使用 AS 关键字,也可以省略
    • select * ,sal + IFNULL(comm,0) as total from emp

5 排序

当我们要给查询出的列进行排序时,可以使用 关键字 ORDER BY, ASC(升序,默认),DESC(降序)

  • 查询所有学生记录,按年龄升序排序:
    • select * from stu order by sage ASC
    • select * from stu order by sage
  • 查询所有学生记录,按年龄降序排序
    • select * from stu order by sage DESC
  • 查询所有雇员,按月薪降序排序,如果月薪相同时,按编号升序排序
    • select * from emp order by sal desc,empno asc

6 聚合函数

sum,avg,max,min,count,聚合函数是用来做纵向运算的函数

  • count():统计指定列不为 NULL 的记录行数
  • max():计算指定列的最大值,如果指定的列是 字符串,那么使用字符串 排序运算
  • min():计算指定列的最小值
  • sum():计算指定列 的数值和,如果不是数值类型,那么 结果为 0
  • avg():计算指定列的 平均值,如果不是数值类型,那么记过为0

count: 纵向统计

  • 查询 emp 表中记录数 :“` select count(*) from emp;
  • 查询 emp 表中有奖金的人数:select count(comm) from emp
  • 查询 emp 表中月薪大于 2500 的人数:
    • select count(*) from emp where sal >2500
  • 统计月薪与奖金之和大于2500元的人数
    • select count(*) from emp where (sal+IFNULL(comm,0))>2500
  • 查询有奖金的人数,以及所有有领导的人数
    • select count(comm),count(mgr) from emp

sum 和 avg : 求和 与求 平均值

  • 查询所有雇员月薪和:select sum(sal) from emp
  • 查询所有雇员月薪和,以及所有雇员奖金和:select sum(sal),sum(comm) from emp
  • 查询所有雇员月薪+奖金和:select sum(sal+IFNULL(comm,0)) from emp
  • 统计所有员工的平均工资:select avg(sal) from emp

max 与 min

  • 查询最高工资和最低工资:select max(sal),min(sal) from emp

7 分组查询

当需要分组查询时需要使用 group by 字句,凡是和 聚合函数同时出现的列名,要写在 group by 之后

分组查询

  • 查询每个部门的部门编号和每个部门的工资和
    • select deptno,SUM(sal) from emp group by deptno
  • 查询每个部门的部门编号以及每个部门的人数
    • select deptno,count(*) from emp group by deptno
  • 查询每个部门的部门编号以及每个部门工资大于1500的人数
    • select deptno,count(*) from emp where sal >1500 group by deptno

having 子句

  • 查询工资总和大于9000的部门编号以及工资和
    • select deptno,sum(sal) from emp group by deptno having sum(sal)>9000

[having 和 where 的区别:having 是在分组之后对数据进行过滤,having 后面可以使用分组函数;where 是在分组之前对数据进行过滤,where 后面不可以使用分组函数;where 是对分组前记录的条件,如果记录不满足 where 的条件,那么该数据就不会参与分组,而 having 是对分组之后的数据进行 约束]

8 limit

用来限定 查询结果 的起始,以及总行数,适合 分页查询

  • 查询5行记录,起始行从0开始
    • select * from emp limit 0,5
  • 查询 10行记录,从第3行开始
    • select * from emp limit 3,10

总结

查询语句 书写顺序 :select – from – where – group by – having – order by – limit
查询语句 执行顺序 :from – where – groub by – having – order by – limit

多表查询

数据库操作中多表查询时很主要的,一定要熟练使用
多表查询有如下几种

  • 合并结果集:union,union all
  • 连接查询
    • 内连接:[INSERT] JOIN ON
    • 外连接:OUTER JOIN ON
      • 左外连接:LEFT JOIN
      • 右外连接:RIGHT JOIN
      • 全外连接:FULL JOIN — MySQL 不支持 全外连接
    • 自然连接:NATURAL JOIN
  • 子查询

合并结果集

就是把 2 个select 语句的查询 结果合并到一起
* UNINO :去除重复查询,例如 :select * from t1 unino select * from t2
* UNINO ALL :不去除重复记录,例如:select * from t1 union all select * from t2
* 要求:被合并的 2 个结果,列数,列类型 都必须相同

连接查询

连接查询就是求出多个表的 乘积 ,例如 t1 连接 t2 ,查询出的 结果 就是 t1*t2,连接查询 我们要 明白 笛卡尔积,有关笛卡尔积 的 概念就不在这里介绍了,大家可以 自己 网上查询

内连接

  • select t1.c1,t1.c2,t2.c1 from t1,t2 where t1.c1 = t2.c1 写为 内连接 就是 :
    • select t1.c1,t1.c2,t2.c1 from t1,t2 inner join t1 on t1.c1 = t2.c1 不适用 where 而是适用 ON

外连接:查询出的结果存在不满足条件的可能

  • select * from emp LEFT OUTER JOIN dept ON emp.deptno = dept.deptno

左外连接 是先查询左表,然后去查询右表,右表中满足条件的显示出来,不满足条件的就显示 NULL
右外连接 是先查询 由表,然后去查询 左表,左表中满足条件显示,不满足 显示 NULL

  • select * from emp right outer join dept on emp.deptno = dept.deptno

连接 不一定是 2 张表,还可能是多张表,田村连接查询我们不需要 整个 笛卡尔积,而只是需要其中的一部分,那么这时就需要使用条件去除不需要的记录,这个条件 一般是使用 主外键 关系确定

自然连接:查询会产生无用的笛卡尔积,使用自然连接无需 给出主外键关系,自然连接会自动找到 该关系

子查询

一个 select 语句中包含另一个 完整的 select 语句,子查询就是嵌套 查询,select 中包含 select ,如果一条语句中存在 2个 或多个 select ,那么就是子查询语句

子查询出现的位置:

  • where 后面:作为条件查询的一部分,这种情况下,还可以使用如下关键字,any 、all
  • from 后面:作为表的一部分

子查询的结果集形式:

  • 单行单列:用于条件
  • 单行多列:用于条件
  • 多行多列:用于表
  • 多行单列:用于条件

你可能感兴趣的:(数据库)