基础SQL语句 下

threcial 发布于 5 天前 11 次阅读


管理数据变化

数据变化主要是三件事:插入、修改、删除

插入数据:INSERT

指定字段插入:

INSERT INTO stu(id, name) VALUES(1, '张三');

批量插入:

INSERT INTO stu(id, name, gender) VALUES
(2, '李四1', '男'),
(3, '李四2', '男'),
(4, '李四3', '男');

给所有字段插入时,可以省略字段列表:

INSERT INTO stu VALUES
(2, '李四', '男', '1999-11-11', 88.88, 'lisi@example.com', '13888888888', 1);

但实际使用时,推荐保留字段列表,因为表结构有可能发生改变,如果省略字段列表,一旦字段顺序或字段数量变化,旧 SQL 语句将失效

修改数据:UPDATE

UPDATE 表名
SET 字段1 = 值1,
    字段2 = 值2
WHERE 条件;

比如:

UPDATE stu
SET sex = '女'
WHERE name = '张三';

一次改多个字段:

UPDATE stu
SET birthday = '1999-12-12',
    score = 99.99
WHERE name = '张三';

如果没有 WHERE,整张表都会被改,所以真正操作数据时,要先用 SELECT 确认影响范围

删除数据:DELETETRUNCATE

删除指定记录:

DELETE FROM stu WHERE name = '张三';

删除全表数据:

DELETE FROM stu;

清空表也可以用:

TRUNCATE TABLE stu;

清空大表时,TRUNCATE 更快,它的效果类似重置整张表,不能像普通 DELETE WHERE 那样精确控制范围

删之前先查询,确定范围

管理数据查询

一个完整的查询骨架可以记成:

SELECT
    字段列表
FROM
   表名列表
WHERE
    条件列表
GROUP BY
    分组字段
HAVING
    分组后条件
ORDER BY
    排序字段
LIMIT
    分页限定;

基础查询

查询全部字段:

SELECT * FROM stu;

查询指定字段:

SELECT name, age FROM stu;

去重:

SELECT DISTINCT address FROM stu;

别名:

SELECT name, math AS 数学成绩, english AS 英语成绩 FROM stu;
SELECT name, math 数学成绩, english 英语成绩 FROM stu;        as可以省略

条件查询:WHERE

SELECT * FROM stu WHERE age > 20;                      大于
SELECT * FROM stu WHERE age >= 20;                     大于等于
SELECT * FROM stu WHERE age > 20 AND age <= 30;        区间
SELECT * FROM stu WHERE age BETWEEN 20 AND 30;         区间
SELECT * FROM stu WHERE age != 18;                    
SELECT * FROM stu WHERE age <> 18;                   不等于的两种写法
SELECT * FROM stu WHERE age IN (18, 20, 22);         多个取值
SELECT * FROM stu WHERE age NOT IN (55, 45, 57);     排除多个取值

NULL 不能用 =!= 判断:

SELECT * FROM stu WHERE english IS NULL;
SELECT * FROM stu WHERE english IS NOT NULL;

模糊查询:LIKE

通配符:

_ :单个任意字符
% :任意多个字符

用法:

SELECT * FROM stu WHERE name LIKE '马%';             马字开头
SELECT * FROM stu WHERE name LIKE '_花%';            二个字是花
SELECT * FROM stu WHERE name LIKE '%德%';            名字中包含德

排序:ORDER BY

SELECT * FROM stu ORDER BY age;         按年龄升序,默认就是升序
SELECT * FROM stu ORDER BY age ASC;      完整写法
SELECT * FROM stu ORDER BY age DESC;      降序

多个排序条件:

SELECT * FROM stu ORDER BY math DESC, english ASC;

多个排序条件的规则是:先按第一个字段排序,第一个字段相同,再按第二个字段排序

聚合函数:纵向计算

聚合函数是对一列数据做整体计算

COUNT:统计数量
MAX:最大值
MIN:最小值
SUM:求和
AVG:平均值

示例:

SELECT COUNT(*) FROM stu;
SELECT MAX(math) FROM stu;
SELECT MIN(math) FROM stu;
SELECT SUM(math) FROM stu;
SELECT AVG(math) FROM stu;

NULL 不会参与聚合运算

统计行数:

SELECT COUNT(*) FROM stu;
SELECT COUNT(id) FROM stu;

分组查询:GROUP BYHAVING

按性别分组,统计数学平均分:

SELECT sex, AVG(math) FROM stu GROUP BY sex;

先过滤,再分组:

SELECT sex, AVG(math), COUNT(*) FROM stu WHERE math > 70 GROUP BY sex;

分组后再过滤:

SELECT sex, AVG(math), COUNT(*) FROM stu WHERE math > 70 GROUP BY sex HAVING COUNT(*) > 2;

WHERE:分组前过滤,不能直接判断聚合函数
HAVING:分组后过滤,可以判断聚合函数

分页查询:LIMIT

基本格式:

SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询条目数;

起始索引从 0 开始

查询前 3 条:

SELECT * FROM stu LIMIT 0, 3;

从第 4 条开始,查 10 条:

SELECT * FROM stu LIMIT 3, 10;

多表查询

两张表直接联查:

SELECT * FROM emp, dept;

会得到笛卡尔积,比如 6 个员工、4 个部门,结果就是 24 行,其中大量是无意义组合

所以使用多表查询必须添加关联条件:

SELECT * FROM emp, dept WHERE emp.dep_id = dept.id;

写多表查询的关键是:表和表靠哪个字段关联?要保留匹配数据,还是保留某一边的全部数据?

内连接:

SELECT * FROM emp INNER JOIN dept ON emp.dep_id = dept.did;

只保留两边都匹配的数据

外连接:

SELECT * FROM emp LEFT JOIN dept ON emp.dep_id = dept.did;

保留左表 emp 的全部数据,右表 dept 能匹配就显示,不能匹配就显示 NULL

SELECT * FROM emp RIGHT JOIN dept ON emp.dep_id = dept.did;

保留右表 dept 的全部数据,左表 emp 能匹配就显示,不能匹配就显示 NULL

子查询:把查询结果当条件或临时表

子查询按结果形态分几种

单行单列:当普通值用

SELECT * FROM emp WHERE salary = 
( SELECT salary FROM emp WHERE name = '猪八戒');

多行单列:配合 INNOT IN

SELECT * FROM emp WHERE dep_id IN 
( SELECT id FROM dept WHERE dname = '财务部' OR dname = '市场部');

多行多列:当临时表用

SELECT * FROM ( SELECT * FROM emp  WHERE join_date > '2011-11-11') t1, dept WHERE t1.dep_id = dept.did;

这里的 t1 是派生表别名,不能省略