SQL语言入门:从增删改查到复杂查询
摘要
本文是SQL语言的全面入门指南,从基础的增删改查(CRUD)操作到高级查询技巧。通过实际示例、操作演示和最佳实践,帮助读者快速掌握SQL核心功能。包含基础语法、常用函数、表连接、子查询和性能优化等内容,适合数据库初学者和需要复习SQL的开发人员。
一、SQL基础概述
SQL(Structured Query Language)是用于管理关系型数据库的标准语言,主要包括三类命令:
graph TD
A[SQL命令分类] --> B[DDL 数据定义]
A --> C[DML 数据操作]
A --> D[DCL 数据控制]
B --> E[CREATE,ALTER,DROP]
C --> F[SELECT,INSERT,UPDATE,DELETE]
D --> G[GRANT,REVOKE]
数据库准备
先创建一个简单的学生数据库作为示例:
CREATE DATABASE school;
USE school;
CREATE TABLE students (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
gender ENUM('M','F'),
birth_date DATE,
class_id INT,
score DECIMAL(5,2)
);
CREATE TABLE classes (
id INT PRIMARY KEY,
name VARCHAR(50),
teacher VARCHAR(50)
);
二、CRUD基础操作
1. 插入数据(INSERT)
-- 单条插入
INSERT INTO students (name, gender, birth_date, class_id, score)
VALUES ('张三', 'M', '2005-03-15', 1, 89.5);
-- 批量插入
INSERT INTO classes VALUES
(1, '高一(1)班', '王老师'),
(2, '高一(2)班', '李老师');
2. 查询数据(SELECT)
-- 基本查询
SELECT * FROM students;
-- 条件查询
SELECT name, score FROM students WHERE score > 90;
-- 排序
SELECT * FROM students ORDER BY score DESC;
-- 分页(MySQL语法)
SELECT * FROM students LIMIT 5 OFFSET 0;
3. 更新数据(UPDATE)
UPDATE students
SET score = score + 5
WHERE gender = 'F' AND score < 85;
4. 删除数据(DELETE)
-- 删除特定记录
DELETE FROM students WHERE id = 3;
-- 清空表(危险!)
TRUNCATE TABLE backup_students;
三、高级查询技巧
1. 表连接(JOIN)
连接类型 | 说明 | 示例 |
---|---|---|
INNER JOIN | 只返回匹配的行 | SELECT s.name, c.name FROM students s JOIN classes c ON s.class_id = c.id |
LEFT JOIN | 返回左表所有行 | SELECT s.name, c.teacher FROM students s LEFT JOIN classes c ON... |
RIGHT JOIN | 返回右表所有行 | SELECT ... RIGHT JOIN ... |
FULL OUTER JOIN | 返回两表所有行(MySQL不支持) | 在MySQL中需用UNION模拟 |
2. 聚合函数
-- 常用聚合函数
SELECT
COUNT(*) AS total,
AVG(score) AS avg_score,
MAX(score) AS top_score,
MIN(score) AS min_score,
SUM(score) AS sum_score
FROM students;
-- 分组统计
SELECT
class_id,
COUNT(*) AS student_count,
AVG(score) AS avg_score
FROM students
GROUP BY class_id
HAVING avg_score > 75;
3. 子查询
-- WHERE子句中的子查询
SELECT name FROM students
WHERE score > (SELECT AVG(score) FROM students);
-- FROM子句中的子查询
SELECT c.name, avg_scores.avg_score
FROM classes c JOIN (
SELECT class_id, AVG(score) AS avg_score
FROM students
GROUP BY class_id
) avg_scores ON c.id = avg_scores.class_id;
4. 常用函数
-- 字符串函数
SELECT CONCAT(name, '(', gender, ')') AS info,
UPPER(name) AS upper_name,
SUBSTRING(name, 1, 1) AS first_letter
FROM students;
-- 日期函数
SELECT name,
YEAR(birth_date) AS birth_year,
DATEDIFF(NOW(), birth_date)/365 AS age
FROM students;
-- 条件表达式
SELECT name, score,
CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
ELSE 'C'
END AS grade
FROM students;
四、视图与索引
1. 创建视图
CREATE VIEW top_students AS
SELECT s.name, s.score, c.name AS class_name
FROM students s JOIN classes c ON s.class_id = c.id
WHERE s.score > 90
ORDER BY s.score DESC;
-- 使用视图
SELECT * FROM top_students;
2. 索引优化
-- 创建索引
CREATE INDEX idx_score ON students(score);
CREATE INDEX idx_class_score ON students(class_id, score DESC);
-- 查看查询执行计划
EXPLAIN SELECT * FROM students WHERE score > 85;
五、事务处理
-- 事务示例
START TRANSACTION;
UPDATE accounts SET balance = balance - 100
WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100
WHERE user_id = 2;
-- 如果执行成功
COMMIT;
-- 如果出现错误
-- ROLLBACK;
ACID特性:
- Atomicity(原子性)
- Consistency(一致性)
- Isolation(隔离性)
- Durability(持久性)
六、SQL最佳实践
-
命名规范:
- 表名使用复数形式(
users
而非user
) - 列名使用下划线分隔(
created_at
)
- 表名使用复数形式(
-
查询优化:
-- 避免使用SELECT * SELECT id, name FROM students; -- 使用LIMIT限制大数据集 SELECT * FROM large_table LIMIT 100;
-
安全注意事项:
# 错误方式(易受SQL注入攻击) "SELECT * FROM users WHERE id = " + user_input # 正确方式(使用参数化查询) "SELECT * FROM users WHERE id = %s", (user_input,)
-
常见错误:
- 混淆GROUP BY和HAVING的使用
- 在多表连接中忘记指定表别名
- 在事务中忘记提交或回滚
七、学习资源推荐
-
在线练习平台:
- SQLZoo
- LeetCode数据库题库
-
进阶学习:
- 《SQL必知必会》
- 《高性能MySQL》
- PostgreSQL官方文档
-
可视化工具:
- MySQL Workbench
- DBeaver
- TablePlus
结语
SQL作为与数据对话的语言,掌握它就如同获得了打开数据世界的钥匙。记住:
"数据不会说谎,但SQL查询可以让你看到不同的真相。"