一、什么是SQL?
Structured Query Language:结构化查询语言
其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方,称为"方言"。
二、SQL通用语法
-
SQL语句可以单行或多行书写,以分号结尾。
-
可使用空格和缩进来增强语句的可读性。
-
MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。
-
3种注释:
-
单行注释:-- 注释内容 或 # 注释内容(mysql特有)
-
多行注释: /* 注释 */
三、SQL分类
1、数据查询语言(DQL, Data Query Language)
核心作用:从数据库中查询 / 检索数据(仅读取,不修改数据),是最常用的 SQL 类别。
核心关键字 :SELECT(核心)、FROM、WHERE、GROUP BY、HAVING、ORDER BY、LIMIT、JOIN 等。
例如:
sql
-- 查询年龄大于20的用户姓名和手机号,按年龄降序排列
SELECT name, phone
FROM users
WHERE age > 20
ORDER BY age DESC
-- LIMIT 10;
2、数据操作语言(DML, Data Manipulation Language)
核心作用:操作(增 / 删 / 改)数据库中的数据(仅修改数据内容,不改变表结构)。
核心关键字:`INSERT`(新增)、`UPDATE`(修改)、`DELETE`(删除)、`MERGE`(合并,部分数据库支持)。
例如:
sql
-- 新增一条用户记录
INSERT INTO users (name, age, phone) VALUES ('张三', 25, '13800138000');
-- 修改用户手机号
UPDATE users SET phone = '13900139000' WHERE id = 1;
-- 删除年龄小于18的用户
DELETE FROM users WHERE age < 18;
3、数据定义语言(DDL, Data Definition Language)
核心作用:定义 / 修改 / 删除数据库对象(表、索引、视图、触发器、数据库等)的结构,操作会直接生效(无需事务提交)。
核心关键字 :CREATE(创建)、ALTER(修改)、DROP(删除)、TRUNCATE(清空表,属于 DDL 而非 DML)、RENAME(重命名)。
执行后通常需要 COMMIT(提交)确认修改,或 ROLLBACK(回滚)撤销修改(事务控制)。
例如:
sql
-- 创建用户表
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age INT,
phone VARCHAR(20) UNIQUE
);
-- 给用户表新增email字段
ALTER TABLE users ADD COLUMN email VARCHAR(100);
-- 删除用户表
DROP TABLE users;
-- 清空用户表(删除所有数据且不可回滚)
-- TRUNCATE TABLE users;
4、数据控制语言(DCL, Data Control Language)
核心作用:管理数据库的权限和事务,控制用户对数据库的访问权限、事务提交 / 回滚等。
核心关键字 :GRANT(授权)、REVOKE(撤销权限)、COMMIT(提交事务)、ROLLBACK(回滚事务)、SAVEPOINT(保存点)、SET TRANSACTION(设置事务属性)。
例如:
sql
-- 授予用户test对users表的查询/插入权限
GRANT SELECT, INSERT ON users TO 'test'@'localhost';
-- 撤销test用户的插入权限
REVOKE INSERT ON users FROM 'test'@'localhost';
-- 提交事务(确认DML操作)
COMMIT;
-- 回滚事务(撤销未提交的DML操作)
ROLLBACK;
5、事务控制语言(TCL, Transaction Control Language)
补充说明:部分分类体系中,TCL 会从 DCL 中独立出来,专门聚焦事务管理(本质是 DCL 的子集)。
核心关键字 :COMMIT、ROLLBACK、SAVEPOINT。
例如:
sql
-- 开启事务(部分数据库需显式声明)
START TRANSACTION;
UPDATE users SET age = 26 WHERE id = 1;
-- 设置保存点
SAVEPOINT sp1;
DELETE FROM users WHERE id = 2;
-- 回滚到保存点(仅撤销删除操作,修改操作保留)
ROLLBACK TO sp1;
-- 提交最终修改
COMMIT;
四、SQL重要分类知识
1、DDL:操作数据库、表
1)C(Create):创建
创建数据库
sql
create database 数据库名称;
创建数据库,判断不存在,再创建:
sql
create database [if not exists] 数据库名称;
创建数据库,并指定字符集:
sql
create database 数据库名称 character set 字符集名;
练习:创建db4数据库,判断是否存在,并指定字符集为gbk
sql
create database if not exists db4 character set gbk;
2)R(Retrieve):查询
查询所有数据的名称:
sql
show databases;
查询某个数据库的字符集:查询某个数据库的创建语句
sql
show create database 数据库名称;
查看表信息
sql
desc 表名
3)U(Update):修改
修改数据库的字符集:
sql
alter database db4 character set utf8;
4)D(Delete):删除
删除数据库:
sql
drop database 数据库名称;
判断数据库存在,存在再删除:
sql
drop database if exists 数据库名称;
5)使用数据库
sql
use 数据库名称;
6)查询当前正在使用的数据库名称
sql
select database();
2、操作表 CRUD
1)C(Create):创建
sql
-- 语法:
create table 表名(
列名1 数据类型1,
列名2 数据类型2,
......
列名3 数据类型n
);
--- 注意:最后一列,不需要加逗号
2)数据类型:
-
int:整数类型
age int,
-
double:小数类型
score double(5,2)
-
date:日期,只包含年月日,yyyy-MM-dd
-
datetime:日期,包含年月日时分秒 yyyy-MM-dd HH:mm:ss
-
timestamp:时间戳类型 包含年月日时分秒 yyyy-MM-dd HH:mm:ss
-
varchar:字符串
name varchar(20):姓名最大20字符
练习:
**(1)**创建表
sql
create table student(
id int,
name varchar(32),
age int,
score double(4,1),
birthday date,
insert_time timestamp
);
(2)复制表
sql
-- 仅复制表结构
create table if not exists 表名 like 被复制的表名;
-- 整体复制
create table if not exists 表名 as select语句
3)R(Retrieve):查询
查询某个数据库中所有的表名称
sql
show tables;
查询表结构
sql
-- 仅查看表结构
desc 表名;
-- 生成DDL
show create table 表名;
4)U(Update):修改
修改表名
sql
alter table 表名 rename to 新表名;
rename table 表名 to 新表名
修改表的字符集
sql
alter table 表名 character set 字符集名称;
查看某张表的字符集
sql
show create table 表名;
添加一列
sql
alter table 表名 add 列名 数据类型;
修改列名称 类型
sql
-- 字段名和数据类型
alter table 表名 change 列名 新列名 新数据类型;
-- 只修改数据类型
alter table 表名 modify 列名 新数据类型;
删除列
sql
alter table 表名 drop 列名;
-- drop table/database
table_name/database_name
5)D(Delete):删除
sql
drop table 表名;
drop table if exists 表名;
3、DML:增删改表中数据
1)添加数据
语法:
sql
insert into 表名(列名1,列名2,列名3,......,列名n) values(值1,值2,......值n);0 | null,值2,......值n
# insert select 将select查询出来的数据插入到目标表中
insert into 表名
select statement;
注意:
1.列名和值要一一对应;只需要对应字段数量相同
2.如果表名后,不定义列名,则默认给所有列添加值
insert into 表名 values(值1,值2,值3,......值n);
3.除了数字类型,其他类型需要使用引号(单双都可以)引起来
2)删除数据
语法:
sql
delete from 表名 [where条件]
注意:
1.如果不加条件,则删除表中所有记录
2.如果要删除所有记录
delete from 表名; --不推荐使用。有多少条记录就会执行多少次删除操作
truncate table 表名; --推荐使用,效率高 先删除表,然后再创建一张一样的表。
3)修改数据
语法:
sql
update 表名 set 列名1 = 值1,列名2 = 值2,......
[where条件];
注意:如果不加任何条件,则会将表中所有记录全部修改。
4、DQL:查询表中的记录
1)语法
sql
select
字段列表
from
表名列表
where
条件列表
group by
分组字段
having
分组之后的条件
order by
排序
limit
分页限定
2)基础查询
1.多个字段的查询
sql
select 字段名1,字段名2... from 表名;
注意:如果查询所有字段,则可以使用*来替代字段列表。
2.去除重复:distinct
3.计算列
一般可以使用四则运算计算一些列值。(一般只会进行数值型的计算)
null参与的运算,计算结果都为null
4.起别名:
as
as也可以省略
3)条件查询
1.where子句后跟条件
2.运算符
>、<、<=、>=、=、<>、<=>
BETWEEN...AND
IN(集合)
LIKE:模糊查询
_:单个任意字符
%:多个任意字符
IS NULL
IS NOT NULL
注意 null 和 空字符串'' 的区别
and
or
not
示例
sql
SELECT * FROM student WHERE age > 20;
SELECT * FROM student WHERE age >= 20;
SELECT * FROM student WHERE age =20;
SELECT * FROM student WHERE age != 20;
SELECT * FROM student WHERE age <> 20;
SELECT * FROM student WHERE age >=20 && age <=30;
SELECT * FROM student WHERE age >=20 AND age <=30;
SELECT * FROM student WHERE age BETWEEN 20 AND 30;
SELECT * FROM student WHERE age=22 OR age=20 OR age=25;
SELECT * FROM student WHERE age IN(22,18,55);
SELECT * FROM student WHERE english IS NOT NULL;
SELECT * FROM student WHERE NAME LIKE '马%';
SELECT * FROM student WHERE NAME LIKE "_化";
SELECT * FROM student WHERE NAME LIKE "___";
SELECT * FROM student WHERE NAME LIKE "%景%"
show variables like "%char%"
4)排序查询
1、语法:order by 子句
order by 排序字段1 排序方式1,排序字段2 排序方式2...
2、排序方式:
-
ASC:升序,默认的
-
DESC:降序
注意:如果又多个排序条件,则当前边的条件值一样时,才会判断第二条件
5)聚合函数
将一列数据作为一个整体,进行纵向的计算
注意:聚合函数的计算,排除null值(可使用ifnull函数)
1、count:计算个数
一般选择非空的列:主键
例如:
sql
SELECT COUNT(NAME) FROM student;
2、max:计算最大值
例如:
sql
SELECT MAX(math) FROM student;
3、min:计算最小值
例如:
sql
SELECT MIN(math) FROM student;
4、sum:计算和
例如:
sql
SELECT SUM(english) FROM student;
5、avg:计算平均值
例如:
sql
SELECT AVG(math) FROM student;
6)分组查询
语法:group by 分组字段
注意:
1.分组之后查询的字段:分组字段、聚合函数
2.where和having的区别?
where在分组之前进行限定,如果不满足条件,则不参与分组。
having在分组之后进行限定,如果不满足结果,则不会被查询出来
where后不可以跟聚合函数,having可以进行聚合函数的判断
例如:
1、按照性别分组,分别查询男、女同学的平均分
sql
SELECT sex,AVG(math) FROM student GROUP BY sex;
2、按照性别分组,分别查询男、女同学的平均分,人数
sql
SELECT sex,AVG(math),COUNT(id)
FROM
student
GROUP BY sex;
3、按照性别分组,分别查询男、女同学的平均分,人数 要求:分数不低于70分的人,不参与分组。
sql
SELECT sex,AVG(math),COUNT(id)
FROM student
WHERE math>70 GROUP BY sex;
4、按照性别分组,分别查询男、女同学的平均分,人数 要求:分数不低于70分的人,不参与分组,分组之后,人数大于2人。
sql
SELECT sex,AVG(math),COUNT(id)
FROM student
WHERE math>70
GROUP BY sex
HAVING COUNT(id)>2;
7)分页查询:
-
语法:limit 开始的索引,每页查询的条数
-
公式:开始的索引 = (当前的页码 -1) * 每页显示的条数
-
例:
- 每页显示3条记录
sql
SELECT * FROM student LIMIT 0,3; 第一页
SELECT * FROM student LIMIT 3,3; 第二页
SELECT * FROM student LIMIT 6,3; 第三页
5、DCL:管理用户,授权
1)管理用户
(1)添加用户:
关闭密码复杂验证
vbscript
set global validate_password_policy=0;
set global validate_password_length=1;
语法:
sql
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
例子:
sql
CREATE USER 'zhangsan'@'localhost' IDENTIFIED BY '123';
CREATE USER 'lisi'@'%' IDENTIFIED BY '123';
(2)删除用户:
语法:
sql
DROP USER '用户名'@'主机名';
例子:
sql
DROP USER 'base'@'%';
(3)修改用户密码:
语法:
sql
-- 老版本的写法
-- UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';
SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');
例子:
sql
set password for 'lisi'@'%' = password('234567');
(4)查询用户:
切换到mysql数据库
sql
USE mysql;
查询user表
sql
select * from user;
2)权限管理:
(1)查询权限:
语法:
sql
SHOW GRANTS FOR '用户名'@'主机名';
SHOW GRANTS FOR 'lisi'@'%';
(2)授予权限:
语法:
sql
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名' [with grant option];
例子:
sql
-- 将表db3.account的SELECT ,DELETE, UPDATE权限授予用户'lisi'@'%'
GRANT SELECT ,DELETE, UPDATE ON db3.account TO 'lisi'@'%';
-- 给zhangsan用户所有权限
GRANT ALL ON *.* TO 'zhangsan'@'localhost'
(3)撤销权限:
语法:
sql
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
例子:
sql
-- 将用户'lisi'@'%'对于表db3.account的更新权限撤销
REVOKE UPDATE ON db3.account FROM 'lisi'@'%';
-- 给lisi用户撤销所有权限
REVOKE ALL ON *.* FROM 'lisi'@'%';
五、多表查询
1、准备
1)准备sql
sql
-- 创建部门表
CREATE TABLE dept(
id INT PRIMARY KEY auto_increment,
NAME VARCHAR(20)
);
-- 插入数据
INSERT INTO dept(NAME) VALUES ('开发部'),('市场部'),('财务部');
-- 创建员工表
CREATE TABLE emp(
id INT PRIMARY KEY auto_increment,
NAME VARCHAR(10),
gender CHAR(1), -- 性别
salary DOUBLE, -- 工资
join_date DATE, -- 入职日期
dept_id INT,
FOREIGN KEY(dept_id) REFERENCES dept(id) -- 外键,关联部门表的主键
);
-- 插入数据
INSERT INTO emp(NAME,gender,salary,join_date,dept_id)
VALUES ('孙悟空','男',7200,'2013-02-24',1),
('猪八戒','男',3600,'2010-12-02',2),
('唐僧','男',9000,'2008-08-08',2),
('白骨精','女',5000,'2015-10-07',3),
('蜘蛛精','女',4500,'2011-03-14',1);
2)笛卡尔积:
有两个集合A,B 取这两个集合的所有组成情况。
例如:
A:(a,b,c)
B:(1,2,3)
A与B作笛卡尔积---> a,1 a,2 a,3 b,1 b,2 b,3 c,1 c,2 c,3
2、消除无用数据
1)内连接查询:
隐式内连接:
使用where条件消除无用数据
sql
-- 查询所有员工信息和对应的部门信息
SELECT * FROM emp,dept WHERE emp.dept_id=dept.id;
-- 查询员工表的名称,性别。部门表的名称
SELECT emp.`NAME`
,emp.gender
,dept.`NAME`
FROM emp,dept
WHERE emp.dept_id=dept.id;
-- 或者
SELECT t1.`NAME`
,t1.gender
,t2.`NAME`
FROM emp as t1,dept as t2
WHERE t1.dept_id=t2.id;
显式内连接:
sql
--语法:select 字段列表 from 表名1 [inner] join 表名2 on 条件
SELECT * FROM emp INNER JOIN dept ON emp.dept_id=dept.id;
2)外连接查询:
左外连接:
sql
语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;
--查询的是左表所有数据以及其交集部分。
右外连接:
sql
语法:select 字段列表 from 表1 right [outer] join 表2 on 条件;
--查询的是右表所有数据以及其交集部分。
3)子查询:
查询中嵌套查询,称嵌套查询为子查询。
sql
-- 查询工资最高的员工信息
-- 1.查询最高的工资是多少 9000
SELECT MAX(salary) FROM emp;
-- 2.查询员工信息,并且工资等于9000的
SELECT * FROM emp WHERE emp.salary=9000;
-- 一条sql就完成这个操作
SELECT * FROM emp WHERE emp.salary = (SELECT MAX(salary) FROM emp);
子查询不同情况:
子查询的结果是单行单列的:
sql
--子查询可以作为条件,使用运算符去判断。 运算符:> >= < <= =
--查询员工工资小于平均工资的人
SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);
子查询的结果是多行单列的:
sql
--子查询可以作为集合,使用in、not int
--查询财务部和市场部所有员工信息
SELECT id FROM dept WHERE `NAME`='财务部' OR `NAME`='市场部';
SELECT * FROM emp WHERE dept_id=3 OR dept_id=2;
--使用子查询
SELECT * FROM emp WHERE dept_id in (SELECT id FROM dept WHERE `NAME`='财务部' OR `NAME`='市场部');
子查询的结果是多行多列的
sql
--子查询可以作为一张虚拟表参与查询
--查询员工入职日期是2011-11-11日之后的员工信息和部门信息
-- 子查询
select * from dept t1
join
(select * from emp where emp.join_date > '2011-11-11') t2 where t1.id = t2.dept_id;
--普通内连接查询
select * from emp t1,dept t2 where t1.dept_id = t2.id and t1.join_date > '2011-11-11'
4)表的拼接
拼接时两张表的结构必须完全一致
-
union 对数据进行去重
-
union all
六、Linux 导入导出数据
不是在mysql中运行 是在Linux中执行 即终端
1、导入数据
sql
-- 本地导入数据
load data local infile '路径' into table 表名 fields terminated by '分隔符';
2、导出数据
sql
# 数据库stu 表students 路径
mysqldump -uroot -p stu students > /root/data/mydb.sql
# 可以加到.bashrc中
alias db_backup='mysqldump -uroot -p stu students > /root/data/mydb_$(date +%Y%m%d).sql'
# 备份并压缩(生成 .sql.gz,节省空间)
alias db_backup='mysqldump -uroot -p --single-transaction stu students | gzip > /root/data/mydb_$(date +%Y%m%d).sql.gz'
3、查看DDL & 查看当前数据库
sql
-- 查看DDL语句
show crete table students;
-- 查看当前数据库
select database();
4、限制查询
limit 关键字
sql
select * from students limit 10;