# 添加记录

INSERT [INTO] tbl_name[(col_name, ...)] {VALUE|VALUES}(VALUES ...);

# 不指定字段名称

INSERT tbl_name VALUE(value...);
INSERT user VALUE(1, 'king', 24, 'king@qq.com');
INSERT user VALUES(NULL, 'queue', 24, 'queue@qq.com');
INSERT user VALUES(DEFAULT, 'lily', 24, 'lily@qq.com');

# 指定字段名称

INSERT tbl_name(字段名称,...) VALUES(值,...);
INSERT user(username,email) VALUES('rose', 'rose@qq.com');

# INSERT ... SET

INSERT tbl_name SET 字段名称=值,...;

# INSERT ... SELECT

INSERT tbl_name[(字段名称,...)] SELECT 字段名称,... FROM tbl_name [WHERE 条件];

# 一次添加多条记录

INSERT tbl_name[(字段名称,...)] VALUES(值,...),(值,...),(值,...);

# 修改记录

UPDATE tbl_name SET 字段名称=值,字段名称=值 [WHERE 条件];
UPDATE user SET age=29 WHERE id=1;
UPDATE user SET age=age-20,email=DEFAULT WHERE id<=5;

如果不添加条件,整个表中的记录都会被更新

# 删除记录

DELETE FROM tbl_name [WHERE 条件];
DELETE FROM user WHERE username='king';
DELETE FROM user WHERE age=24;
DELETE FROM user;

如果不添加条件,表中所有记录都会被删除
DELETE清空数据表的时候不会重置AUTO_INCREMENT的值,可以通过ALTER语句将其重置为1

# 彻底清空数据表

TRUNCATE [TABLE] tbl_name

清除表中所有记录并重置AUTO_INCREMENT的值

# 查询记录

SELECT select_expr,... FROM tbl_name
[WHERE 条件] 
[GROUP BY {col_name|position} HAVING 二次筛选]
[ORDER BY {col_name|position|expr} [ASC|DESC]]
[LIMIT 限制结果集的显示条数]

# 查询表中所有记录

SELECT * FROM tbl_name;
-- *表示所有字段
SELECT * FROM user1;

# 查询指定字段

SELECT 字段名称,... FROM tbl_name;
SELECT username,addr,age FROM user1;

# 不打开数据库查询

SELECT 字段名称,... FROM db_name.tbl_name;

# 给字段起别名

SELECT 字段名称 [AS] 别名名称, ... FROM tbl_name;

SELECT id AS '编号',username AS '用户名',sex AS '性别' FROM  user1;

# 给数据表起别名

SELECT 字段名称,... FROM tbl_name [AS] 别名;

SELECT id,username FROM user1 AS u;

# 表名.字段名的形式

SELECT tbl_name.col_name,... FROM tbl_name;

SELECT user1.id, user1.username FROM user1;

# WHERE 条件

筛选出符合条件的记录

# 比较运算符

> >= < <= = != <> <=>

SELECT id,username FROM user1
WHERE id=5;

-- 检测NULL值
SELECT id,username,age,userDesc FROM user1 WHERE userDesc<=>NULL;

<=> 和 = 的区别:<=>可以检测NULL值

# IS [NOT] NULL

检测是否为NULL或者NOT NULL

SELECT id,username,age,userDesc FROM user1 WHERE userDesc IS NULL;

# 指定范围

[NOT] BETWEEN...AND

SELECT id,username,age,sex FROM user1
WHERE age BETWEEN 18 AND 30;

# 指定集合

[NOT] IN(值,...)

SELECT id,username,age FROM user1
WHERE id IN(1,3,5,7,9);

SELECT id,username,age FROM user1
WHERE username IN('king','queue');

# 逻辑运算符

  • AND 逻辑与

    SELECT id,username,age,sex FROM user1
    WHERE sex='男' AND age>=20;
    
    SELECT id,username,age,sex,salary,addr FROM user1 WHERE salary BETWEEN 60000 AND 100000 AND sex='男' AND addr='北京';
    
  • OR 逻辑或

    SELECT id,username,age FROM user1
    WHERE id=1 OR username='queue';
    

# 匹配字符

[NOT] LIKE

SELECT id,username,age FROM user1
WHERE username='king';

SELECT id,username,age FROM user1
WHERE username LIKE 'king';

通配符

  • % 任意长度的字符串
  • _ 任意一个字符
SELECT id,username,age,sex FROM user1
WHERE username LIKE '%三%';

-- 用户名长度为三位的用户
SELECT id,username,age,sex FROM user1
WHERE username LIKE '___';

SELECT id,username,age,sex FROM user1
WHERE username LIKE '张_%';

-- 默认忽略大小写
SELECT id,username,age FROM user1
WHERE username LIKE '%K%';

# GROUP BY 分组

把值相同放到一个组中,最终查询出的结果只会显示组中一条记录

-- 按照性别分组sex
SELECT id,username,age,sex FROM user1
GROUP BY sex;

# GROUP_CONCAT()

分组配合GROUP_CONCAT()查看组中某个字段的详细信息

-- 按照性别分组,查询组中的用户名有哪些
SELECT GROUP_CONCAT(username),age,sex,addr FROM user1
GROUP BY sex;

# 配合聚合函数使用

  • COUNT():统计记录总数
  • SUM():求和
  • MAX():求最大值
  • MIN():求最小值
  • AVG():求平均值
SELECT COUNT(*) AS total_users FROM user1;
SELECT COUNT(id) FROM user1;

如果COUNT(字段名称),字段中的值为NULL,不统计进来,写COUNT(*) 统计NULL值

-- 按照sex分组,得到用户名详情,并且分别统计组中的总人数
SELECT sex,GROUP_CONCAT(username) AS usersDetail,COUNT(*) AS totalUsers FROM user1 GROUP BY sex;

-- 按照addr分组,得到用户名的详情,总人数,得到组中年龄的综合,年龄的最大值、最小值、平均值
SELECT addr,GROUP_CONCAT(username) AS usersDetail,
COUNT(*) AS totalUsers,
SUM(age) AS sum_age,
MAX(age) AS max_age,
MIN(age) AS min_age,
AVG(age) AS avg_age
FROM user1
GROUP BY addr;

# 配合WITH ROLLUP关键词

会在记录末尾添加一条记录,是上面所有记录的总和

SELECT GROUP_CONCAT(username) AS usersDetail,
COUNT(*) AS totalUsers
FROM user1
GROUP BY sex
WITH ROLLUP;

# 按照字段位置分组

SELECT addr,GROUP_CONCAT(username) AS usersDetail,
COUNT(*) AS totalUsers,
SUM(age) AS sum_age,
MAX(age) AS max_age,
MIN(age) AS min_age,
AVG(age) AS avg_age
FROM user1
GROUP BY 1;
-- GROUP BY 1表示按照addr分组

# HAVING子句,对分组结果进行二次筛选

-- 按照addr分组,统计总人数
SELECT addr,
GROUP_CONCAT(username) AS usersDetail,
COUNT(*) AS totalUsers
FROM user1
GROUP BY addr;

-- 对分组结果进行二次筛选,条件是组中总人数>=3
SELECT addr,
GROUP_CONCAT(username) AS usersDetail,
COUNT(*) AS totalUsers
FROM user1
GROUP BY addr
HAVING COUNT(*)>=3;

SELECT addr,
GROUP_CONCAT(username) AS usersDetail,
COUNT(*) AS totalUsers
FROM user1
GROUP BY addr
HAVING totalUsers>=3;

# ORDER BY 排序

ORDER BY 字段名称 ASC|DESC

SELECT id,username,age
FROM user1
ORDER BY id DESC;

-- 默认升序
SELECT id,username,age
FROM user1
ORDER BY age;

-- 按照多个字段排序
SELECT id,username,age
FROM user1
ORDER BY age ASC, id ASC;

-- 实现随机记录
SELECT id,username,age
FROM user1
ORDER BY RAND();

# LIMIT 限制结果集显示条数

-- 显示结果集的前几条记录
LIMIT row_count
-- 从offset开始,显示几条记录
-- offset从0开始
LIMIT offset,row_count

-- 显示结果集中前5条记录
SELECT id,username,age,sex
FROM user1
LIMIT 5;

SELECT id,username,age,sex
FROM user1
LIMIT 0,5;

-- 显示前3条记录
SELECT id,username,age,sex
FROM user1
LIMIT 0,3;

-- 分页
SELECT id,username,age,sex
FROM user1
LIMIT 0,3;

SELECT id,username,age,sex
FROM user1
LIMIT 3,3;

SELECT id,username,age,sex
FROM user1
LIMIT 6,3;

-- 更新user1表前三条记录,将age+5
UPDATE user1 SET age=age+5 LIMIT 3;

-- 删除user1表前三条记录
DELETE FROM user1 LIMIT 3;

# 完整select语句形式

SELECT addr,
GROUP_CONCAT(username) AS usersDetail,
COUNT(*) AS totalUsers,
SUM(age) AS sum_age,
MAX(age) AS max_age,
MIN(age) AS min_age,
AVG(age) AS avg_age
FROM user1
WHERE id>=2
GROUP BY addr
HAVING totalUsers>=2
ORDER BY totalUsers ASC
LIMIT 0,2;

# 多表查询

# 笛卡尔积形式

SELECT emp.id,emp.username,emp.age,dep.depName FROM emp,dep;

# 内连接形式(用的较多)

查询两个表中符合连接条件的记录

SELECT 字段名称,... FROM tbl_name1 [INNER]   JOIN tbl_name2 ON 连接条件;

SELECT e.id,e.username,e.age,d.depName 
FROM emp AS e
INNER JOIN dep AS d
ON e.depId=d.id;

SELECT p.id,p.productName,p.price,c.cateName,a.username,a.email
FROM products AS p
JOIN admin AS a
ON p.adminId=a.id
JOIN cate AS c
ON p.cateId=c.id
WHERE p.price<1000
ORDER BY p.price DESC
LIMIT 0,2;

# 外连接形式

# 左外连接

先显示左表全部记录,再去右表中查询符合条件的记录,不符合的以NULL代替

SELECT 字段名称,... FROM tbl_name1
LEFT [OUTER] JOIN tbl_name2
ON 条件;

SELECT e.id,e.username,e.age,d.depName 
FROM emp AS e
LEFT OUTER JOIN dep AS d
ON e.depId=d.id;

# 右外连接

先显示右表全部记录,再去左表中查询符合条件的记录,不符合的以NULL代替

SELECT 字段名称,... FROM tbl_name1
RIGHT [OUTER] JOIN tbl_name2
ON 条件;

SELECT e.id,e.username,e.age,d.depName 
FROM emp AS e
RIGHT OUTER JOIN dep AS d
ON e.depId=d.id;

# 外键约束

只有InnoDB存储引擎支持外键

# 创建外键

# 建表时指定外键

字表的外键字段和主表的主键字段类型要相似;如果是数值型要求一致,并且无符号也要一致;如果是字符型,要求类型一致,长度可以不同;

如果外键字段没有创建索引,MySQL会自动帮我们添加索引

子表的外键必须是父表的主键

[CONSTRAINT 外键名称] FOREIGN KEY(字段名称) REFERENCES 主表(字段名称);

CREATE TABLE news(
    id INT UNSIGNED AUTO_INCREMENT KEY,
    title VARCHAR(100) NOT NULL UNIQUE,
    content VARCHAR(1000) NOT NULL,
    cateId TINYINT UNSIGNED NOT NULL,
    FOREIGN KEY(cateId) REFERENCES news_cate(id)
)ENGINE=INNODB;

-- 添加外键名称
CREATE TABLE news(
    id INT UNSIGNED AUTO_INCREMENT KEY,
    title VARCHAR(100) NOT NULL UNIQUE,
    content VARCHAR(1000) NOT NULL,
    cateId TINYINT UNSIGNED NOT NULL,
    CONSTRAINT cateId_fk_newsCate FOREIGN KEY(cateId) REFERENCES news_cate(id)
)ENGINE=INNODB;

# 动态添加外键

ALTER TABLE tbl_name
ADD [CONSTRAINT 外键名称] FOREIGN KEY(外键字段) REFERENCES 主表(主键字段)

ALTER TABLE news
ADD FOREIGN KEY(cateId) REFERENCES news_cate(id);

ALTER TABLE news
ADD CONSTRAINT cateId_fk_newsCate FOREIGN KEY(cateId) REFERENCES news_cate(id);

动态添加外键之前表中的记录一定合法的记录,没有脏值,否则外键添加不成功。

# 动态删除外键

ALTER TABLE tbl_name
DROP FOREIGN KEY fk_name;

ALTER TABLE news
DROP FOREIGN KEY cateId_fk_newsCate;

# 外键约束的参照操作

  • CASCADE: 级联,从父表删除或更新,字表也跟着删除或更新
  • SET NULL: 从父表删除或更新记录,并设置子表的外键列为NULL
  • NO ACTION|RESTRICT: 拒绝对父表做更新或者删除操作
-- 指定级联操作 DELETE CASCADE UPDATE CASCADE

ALTER TABLE news
ADD FOREIGN KEY(cateId) REFERENCES news_cate(id)
ON DELETE CASCADE 
ON UPDATE CASCADE;

# 特殊形式的查询

# 子查询

将一个查询语句嵌套在另一个查询语句中 内层语句查询的结果可以作为外层语句查询的条件

SELECT 字段名称 FROM tbl_name
WHERE col_name=(SELECT col_name FROM tbl_name);

# 由IN引发的子查询

SELECT * FROM emp
WHERE depId IN (SELECT id FROM dep);

SELECT * FROM emp
WHERE depId NOT IN (SELECT id FROM dep);

# 由比较运算符引出的子查询

SELECT id,username,score FROM stu
WHERE score>=(SELECT score FROM level WHERE id=1);

# 由EXISTS引发的子查询

-- 子查询有值(返回真)则前面语句执行
SELECT * FROM emp
WHERE EXISTS (SELECT depName from dep
WHERE id=10);

# ANY SOME ALL关键字子查询

-- >= 中 ANY 表示最小值
SELECT * FROM stu
WHERE score>=ANY(SELECT score FROM level);

-- >= 中 SOME 表示最小值
SELECT * FROM stu
WHERE score>=SOME(SELECT score FROM level);

-- >= 中 ALL 表示最大值
SELECT * FROM stu
WHERE score>=ALL(SELECT score FROM level);

# INSERT ... SELECT

插入另一张数据表的值

INSERT user1(username) 
SELECT username FROM user;

INSERT user2 SET username=(SELECT username FROM stu WHERE id=9);

-- 去掉字段重复值
SELECT DISTINCT(username) FROM user2;

# CREATE ... SELECT

创建表并写入数据

CREATE TABLE user1(
    id INT UNSIGNED AUTO_INCREMENT KEY,
    username VARCHAR(20)
) SELECT id,username FROM emp;

# CREATE ... LIKE

CREATE TABLE tbl_name LIKE tbl_name1;

# 联合查询

# UNION

合并时去除重复记录

SELECT 字段名称,... FROM tbl_name1
UNION
SELECT 字段名称,... FROM tbl_name2;

-- 将user1和user2数据合并到一起
SELECT * from user1
UNION
SELECT * FROM user2;

# UNION ALL

合并时不去除重复记录

SELECT 字段名称,... FROM tbl_name1
UNION ALL
SELECT 字段名称,... FROM tbl_name2;

# 自身连接查询

无限极分类的实现形式

-- 查询所有的分类信息,并且得到其父分类
SELECT s.id,s.cateName AS sCateName,p.cateName AS pCateName
FROM cate AS s
LEFT JOIN cate AS p
ON s.pId=p.id;

-- 查询所有的分类及其子分类
SELECT p.id,p.cateName AS pCateName,s.cateName AS sCateName
FROM cate AS s
RIGHT JOIN cate AS p
ON s.pId=p.id;

-- 查询所有的分类并且得到子分类的数目
SELECT p.id,p.cateName AS pCateName,COUNT(s.cateName) AS count
FROM cate AS s
RIGHT JOIN cate AS p
ON s.pId=p.id
GROUP BY p.cateName
ORDER BY id ASC;
上次更新: 2/13/2025, 3:29:47 AM