【回头看】SQL常用语句和特性整理
回头看系列文章序
自大三起我认识到,随着应用知识的扩展,基础知识的重要性愈加明显。时至今日,已经到了无法忽视的地步,以至于我们必须采取有效措施,认真巩固语言基础、数据库、操作系统等一系列重要基础知识,将零散的知识点体系化,我将这一计划称之为“回头看”。
SQL(Structured Query Language,结构化查询语言),用于关系数据库管理,也是一位熟悉又陌生的老朋友。SQL除了支持对数据库结构的创建、修改以及CRUD操作以外还支持多表联查、简单的逻辑操作等。
此外,SQL作为一个标准,在各类DBMS具体实现时并不一定完全遵守,它们虽然在基础的CRUD操作上没有什么分别,但具体特性却各有设计,被称之为SQL方言。
由此诸多特性,SQL其实不是一个学一遍记住就能完事的知识点,同Linux等诸多实践知识一样,SQL需要结合具体使用场景、具体数据结构具体分析,随用随学,必要时还要结合非关系型数据库管理方式对数据进行整合处理。本篇整合是对常用SQL语句的简单梳理,以备随时查询。
- SQL对大小写不敏感;
- 每条SQL语句末都应接分号以表结束;
- 关系型数据库的层级概念:数据库 - 表 - 记录(行),视图。
数据库结构管理
SQL 对数据库结构的管理包括数据库对象的创建、修改和删除。这些对象包括数据库、表、视图、索引、约束和存储过程等。
数据库操作
-- 创建数据库
CREATE DATABASE database_name;
-- 删除数据库
DROP DATABASE database_name;
-- 切换到数据库
USE DATABASE;
表管理
-- 创建表
CREATE TABLE table_name (
column1 datatype constraints,
column2 datatype constraints,
demo_id INT PRIMARY KEY AUTO_INCREMENT,
demo_name VARCHAR(100) NOT NULL,
...
)
-- 修改表
-- 添加新列
ALTER TABLE table_name ADD column_name datatype;
-- 删除列
ALTER TABLE table_name DROP COLUMN column_name;
-- 修改列的数据类型
ALTER TABLE table_name MODIFY COLUMN column_name new_datatype;
-- 删除表
DROP TABLE table_name;
视图
注意,更新视图无法直接使用UPDATE,应该更新原表数据后重新查询视图。
-- 创建视图
CREATE VIEW view_name AS
SELECT column1, column2, ...
FROM table_name
WHERE condition;
-- 修改视图
CREATE OR REPLACE VIEW view_name AS
SELECT column1, column2, ...
FROM table_name
WHERE condition;
-- 删除视图
DROP VIEW view_name;
索引
-- 编制索引
CREATE INDEX index_name
ON table_name (column_name);
-- 删除索引
DROP INDEX index_name ON table_name;
约束
常用约束类型
- PRIMARY KEY:主键,唯一标识表中的每一行。
- FOREIGN KEY:外键,确保引用完整性。
- UNIQUE:唯一约束,确保列中的所有值唯一。
- NOT NULL:非空约束,确保列中的值不能为空。
- CHECK:检查约束,确保列中的值满足指定条件。
-- 添加约束
ALTER TABLE table_name
ADD CONSTRAINT constraint_name PRIMARY KEY (column_name);
-- 删除约束
ALTER TABLE table_name
DROP CONSTRAINT constraint_name;
触发器
-- 创建触发器
CREATE TRIGGER trigger_name
BEFORE | AFTER INSERT | UPDATE | DELETE
ON table_name
FOR EACH ROW
BEGIN
-- SQL statements
END;
--删除触发器
DROP TRIGGER trigger_name;
存储过程与函数
-- 创建存储过程
CREATE PROCEDURE procedure_name (parameters)
BEGIN
-- SQL statements
END;
-- 创建函数
CREATE FUNCTION function_name (parameters) RETURNS return_datatype
BEGIN
-- SQL statements
RETURN return_value;
END;
-- 删除存储过程/函数
DROP PROCEDURE procedure_name;
DROP FUNCTION function_name;
基本CRUD操作
增(Create)删(Delete)改(Update)查(Read),是每个程序员都逃不过去的坎。此外,SQL也可以和Excel配合使用完成一些数据操作。
查询 SELECT
-- 查询全部
SELECT * FROM table_name
-- 指定查询
SELECT column1, column2 FROM table_name;
-- 条件查询
SELECT * FROM table_name WHERE condition;
-- 查询结果排序
SELECT * FROM table_name
ORDER BY column1 [ASC|DESC];
--限制输出前n条数据
SELECT * FROM table_name
LIMIT n;
插入 INSERT
-- 向表格中插入值
INSERT INTO table_name VALUES (value1, value2, ....)
-- 向指定列插入值
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);
修改 UPDATE
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
删除 DELETE
DELETE FROM table_name WHERE condition;
连接 JOIN
SQL中的JOIN可以根据两表的共有字段将两个表的数据匹配输出,常见JOIN类型包括内连接、左连接、右连接、全连接、交叉连接和自连接。
示例表:employees和departments
employee_id | name | department_id |
---|---|---|
1 | Alice | 1 |
2 | Bob | 2 |
3 | Charlie | 2 |
4 | Daniel | 4 |
department_id | department_name |
---|---|
1 | HR |
2 | IT |
3 | Finance |
内连接(INNER JOIN)与全连接(FULL JOIN)
- 内连接:返回两个表中满足连接条件的所有行。如果在两个表中找不到匹配项,结果集中将不会包含该行。
- 全连接:返回两个表中的所有行。如果在一个表中没有匹配项,结果集中将包含NULL值。注:MySQL不支持全连接。
-- 内连接
SELECT employees.name, departments.department_name
FROM employees
INNER JOIN departments ON employees.department_id = departments.department_id;
-- 全连接
SELECT employees.name, departments.department_name
FROM employees
FULL OUTER JOIN departments ON employees.department_id = departments.department_id;
- 内连接返回结果
name | department_name |
---|---|
Alice | HR |
Bob | IT |
Charlie | IT |
- 全连接返回结果
name | department_name |
---|---|
Alice | HR |
Bob | IT |
Charlie | IT |
Daniel | NULL |
NULL | Finance |
左连接(LEFT JOIN)与右连接(RIGHT JOIN)
- 左连接:返回左表中的所有行,即使右表中没有匹配项。如果右表中没有匹配项,则结果集中对应的列将包含NULL值。
- 右连接:返回右表中的所有行,即使左表中没有匹配项。如果左表中没有匹配项,则结果集中对应的列将包含NULL值。
-- 左连接
SELECT employees.name, departments.department_name
FROM employees
LEFT JOIN departments ON employees.department_id = departments.department_id;
-- 右连接
SELECT employees.name, departments.department_name
FROM employees
RIGHT JOIN departments ON employees.department_id = departments.department_id;
- 左连接返回结果
name | department_name |
---|---|
Alice | HR |
Bob | IT |
Charlie | IT |
Daniel | NULL |
- 右连接返回结果
name | department_name |
---|---|
Alice | HR |
Bob | IT |
Charlie | IT |
NULL | Finance |
交叉连接(CROSS JOIN)
交叉连接返回两个表的笛卡尔积,即每个表中的每一行都与另一个表中的每一行组合。注意:在使用Cross Join时,不用使用on关键字。
SELECT employees.name, departments.department_name
FROM employees
CROSS JOIN departments;
- 交叉连接返回结果
name | department_name |
---|---|
Alice | HR |
Alice | IT |
Alice | Finance |
Bob | HR |
Bob | IT |
Bob | Finance |
Charlie | HR |
Charlie | IT |
Charlie | Finance |
Daniel | HR |
Daniel | IT |
Daniel | Finance |
自连接(SELF JOIN)
自连接是对自身表的连接,用于在同一个表中查找关系。
示例employees表:
employee_id | name | manager_id |
---|---|---|
1 | Alice | NULL |
2 | Bob | 1 |
3 | Charlie | 1 |
SELECT e1.name AS employee, e2.name AS manager FROM employees e1 LEFT JOIN employees e2 ON e1.manager_id = e2.employee_id;
- 自连接输出结果
employee | manager |
---|---|
Alice | NULL |
Bob | Alice |
Charlie | Alice |
常用操作符
SQL 操作符
和许多编程语言一样,SQL提供了丰富的操作符,其类别包括:
- 算术操作符;
- 比较操作符;
- 逻辑操作符;
- 集合操作符;
- 位操作符;
- 字符串操作符;
- 特殊操作符。
其中,算数、比较、逻辑和位运算在各类语言中都大差不差,我在这里着选常用的集合操作符UNION和字符串操作符LIKE进行记录。
联合 UNION
UNION操作符用于合并两个或多个SELECT语句的结果集。
- 所有参与UNION的SELECT语句必须返回相同数量的列;
- 每个SELECT语句中的对应列必须具有相同或兼容的数据类型;
- UNION默认去除重复行。如果希望包含所有结果(包括重复行),可以使用UNION ALL;
- 可以将UNION用于合并来自不同表、视图甚至不同数据库的数据源.
SELECT column1, column2, ...
FROM table1
UNION
SELECT column1, column2, ...
FROM table2;
匹配 LIKE
LIKE 操作符用于在 WHERE 子句中搜索列中的匹配模式。LIKE常与_
和%
组合使用,
SELECT column_name
FROM table_name
WHERE column_name LIKE pattern
%
通配符表示零个或多个字符;_
通配符表示单个字符。
-- 匹配以A开头的字符串
SELECT * FROM employees WHERE name LIKE 'A%';
-- 匹配以e结尾的字符串
SELECT * FROM employees WHERE name LIKE '%e';
-- 匹配包含特定字符串的字符串
SELECT * FROM employees WHERE name LIKE '%li%';
-- 匹配长度为3的字符串
SELECT * FROM employees WHERE name LIKE '___';
-- 匹配第二个字符是l的字符串
SELECT * FROM employees WHERE name LIKE '_l%';