SQL语句详细使用说明 - 适合小白入门
文章目录
- SQL语句详细使用说明 - 适合小白入门
- 一、SQL简介
- 二、数据库基本操作
- 1. 创建数据库
- 2. 查看所有数据库
- 3. 选择数据库
- 4. 删除数据库
- 三、表的基本操作
- 1. 创建表
- 2. 查看所有表
- 3. 查看表结构
- 4. 修改表
- 5. 删除表
- 四、数据操作语言(DML)
- 1. 插入数据(INSERT)
- 2. 查询数据(SELECT)
- 3. 更新数据(UPDATE)
- 4. 删除数据(DELETE)
- 五、聚合函数与分组查询
- 1. 聚合函数
- 2. 分组查询(GROUP BY)
- 六、表连接(JOIN)操作
- 1. 内连接(INNER JOIN)
- 2. 左连接(LEFT JOIN)
- 3. 右连接(RIGHT JOIN)
- 4. 全连接(FULL JOIN)
- 七、子查询
- 1. WHERE子句中的子查询
- 2. FROM子句中的子查询
- 3. IN子查询
- 4. EXISTS子查询
- 八、视图和索引
- 1. 视图(VIEW)
- 2. 索引(INDEX)
- 九、事务处理
- 十、SQL注入防护
- 1. 什么是SQL注入?
- 2. 如何防止SQL注入?
- 十一、SQL常用函数
- 1. 字符串函数
- 2. 日期函数
- 3. 数学函数
- 十二、SQL实用示例
- 1. 学生成绩管理系统示例
- 2. 分页查询示例
- 3. 数据导入导出示例
- 十三、学习建议
SQL语句详细使用说明 - 适合小白入门
一、SQL简介
SQL(Structured Query Language,结构化查询语言)是用于管理关系型数据库的标准语言。无论你使用MySQL、SQL Server、Oracle还是PostgreSQL,基本的SQL语法都是相通的。
本教程将从最基础的SQL知识开始,循序渐进地讲解SQL的各种用法,非常适合SQL初学者。
二、数据库基本操作
1. 创建数据库
-- 创建名为students的数据库
CREATE DATABASE students;-- 创建指定字符集的数据库
CREATE DATABASE students CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
2. 查看所有数据库
-- MySQL和PostgreSQL
SHOW DATABASES;-- SQL Server
SELECT name FROM sys.databases;
3. 选择数据库
-- 使用students数据库
USE students;
4. 删除数据库
-- 删除students数据库
DROP DATABASE students;
三、表的基本操作
1. 创建表
-- 创建学生表
CREATE TABLE student (id INT PRIMARY KEY AUTO_INCREMENT, -- 主键,自动增长name VARCHAR(50) NOT NULL, -- 姓名,不能为空age INT, -- 年龄gender VARCHAR(10), -- 性别class VARCHAR(50), -- 班级create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 创建时间,默认当前时间
);
2. 查看所有表
-- MySQL和PostgreSQL
SHOW TABLES;-- SQL Server
SELECT name FROM sys.tables;
3. 查看表结构
-- MySQL
DESC student;-- PostgreSQL
\d student;-- SQL Server
EXEC sp_columns student;
4. 修改表
-- 添加列
ALTER TABLE student ADD COLUMN email VARCHAR(100);-- 修改列类型
ALTER TABLE student MODIFY COLUMN email VARCHAR(200);-- 修改列名
ALTER TABLE student CHANGE COLUMN email student_email VARCHAR(200);-- 删除列
ALTER TABLE student DROP COLUMN student_email;
5. 删除表
-- 删除student表
DROP TABLE student;
四、数据操作语言(DML)
1. 插入数据(INSERT)
-- 插入一条完整数据
INSERT INTO student (name, age, gender, class)
VALUES ('张三', 18, '男', '计算机1班');-- 插入多条数据
INSERT INTO student (name, age, gender, class)
VALUES ('李四', 19, '女', '计算机1班'),('王五', 18, '男', '计算机2班'),('赵六', 20, '女', '软件1班');-- 插入部分字段数据(其他字段使用默认值或NULL)
INSERT INTO student (name, class)
VALUES ('钱七', '网络1班');
2. 查询数据(SELECT)
-- 查询所有数据
SELECT * FROM student;-- 查询指定字段
SELECT name, age, class FROM student;-- 列名重命名(使用别名)
SELECT name AS 姓名, age AS 年龄, class AS 班级 FROM student;-- 去重查询
SELECT DISTINCT class FROM student;-- 条件查询
SELECT * FROM student WHERE age > 18;
SELECT * FROM student WHERE class = '计算机1班';
SELECT * FROM student WHERE gender = '男' AND age >= 19;
SELECT * FROM student WHERE class = '计算机1班' OR class = '计算机2班';-- 范围查询
SELECT * FROM student WHERE age BETWEEN 18 AND 20;
SELECT * FROM student WHERE class IN ('计算机1班', '软件1班');-- 模糊查询
SELECT * FROM student WHERE name LIKE '张%'; -- 姓张的
SELECT * FROM student WHERE name LIKE '%三'; -- 名字以三结尾的
SELECT * FROM student WHERE name LIKE '%李%'; -- 名字中包含李的-- 空值查询
SELECT * FROM student WHERE age IS NULL;
SELECT * FROM student WHERE age IS NOT NULL;-- 排序查询
SELECT * FROM student ORDER BY age ASC; -- 升序
SELECT * FROM student ORDER BY age DESC; -- 降序
SELECT * FROM student ORDER BY class ASC, age DESC; -- 先按班级升序,再按年龄降序-- 限制查询结果数量
SELECT * FROM student LIMIT 10; -- 只返回前10条
SELECT * FROM student LIMIT 5, 10; -- 从第6条开始,返回10条
3. 更新数据(UPDATE)
-- 更新单条数据
UPDATE student SET age = 19 WHERE id = 1;-- 更新多条数据
UPDATE student SET age = age + 1 WHERE class = '计算机1班';-- 同时更新多个字段
UPDATE student
SET age = 20, class = '计算机3班'
WHERE id = 2;-- 注意:一定要加WHERE条件,否则会更新表中所有数据!
-- 危险操作:UPDATE student SET age = 20;
4. 删除数据(DELETE)
-- 删除单条数据
DELETE FROM student WHERE id = 5;-- 删除多条数据
DELETE FROM student WHERE class = '计算机3班';-- 清空表(保留表结构)
DELETE FROM student;-- 注意:一定要加WHERE条件,否则会删除表中所有数据!
-- 危险操作:DELETE FROM student;
五、聚合函数与分组查询
1. 聚合函数
-- 计算总数
SELECT COUNT(*) FROM student; -- 总行数
SELECT COUNT(age) FROM student; -- age不为NULL的行数-- 求和
SELECT SUM(age) FROM student; -- 年龄总和-- 平均值
SELECT AVG(age) FROM student; -- 平均年龄-- 最大值和最小值
SELECT MAX(age) AS 最大年龄, MIN(age) AS 最小年龄 FROM student;
2. 分组查询(GROUP BY)
-- 按班级分组,统计每个班级的学生人数
SELECT class, COUNT(*) AS 人数 FROM student GROUP BY class;-- 按性别分组,计算每个性别的平均年龄
SELECT gender, AVG(age) AS 平均年龄 FROM student GROUP BY gender;-- 分组后筛选(HAVING)
SELECT class, COUNT(*) AS 人数 FROM student
GROUP BY class
HAVING COUNT(*) > 10; -- 只显示人数大于10的班级-- 综合示例
SELECT class, gender, COUNT(*) AS 人数, AVG(age) AS 平均年龄
FROM student
WHERE age > 18
GROUP BY class, gender
HAVING COUNT(*) > 5
ORDER BY class, gender;
六、表连接(JOIN)操作
假设我们有两个表:
-- 创建学生表
CREATE TABLE student (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,age INT,class_id INT
);-- 创建班级表
CREATE TABLE class (id INT PRIMARY KEY AUTO_INCREMENT,class_name VARCHAR(50) NOT NULL,teacher VARCHAR(50)
);
1. 内连接(INNER JOIN)
-- 查询学生及其所在班级信息
SELECT s.id, s.name, s.age, c.class_name, c.teacher
FROM student s
INNER JOIN class c ON s.class_id = c.id;-- 简化写法(省略INNER关键字)
SELECT s.id, s.name, s.age, c.class_name, c.teacher
FROM student s
JOIN class c ON s.class_id = c.id;
2. 左连接(LEFT JOIN)
-- 查询所有学生及其班级信息,如果学生没有班级也会显示
SELECT s.id, s.name, s.age, c.class_name, c.teacher
FROM student s
LEFT JOIN class c ON s.class_id = c.id;
3. 右连接(RIGHT JOIN)
-- 查询所有班级及其学生信息,如果班级没有学生也会显示
SELECT s.id, s.name, s.age, c.class_name, c.teacher
FROM student s
RIGHT JOIN class c ON s.class_id = c.id;
4. 全连接(FULL JOIN)
-- 查询所有学生和所有班级信息(MySQL不支持FULL JOIN)
-- PostgreSQL和SQL Server支持
SELECT s.id, s.name, s.age, c.class_name, c.teacher
FROM student s
FULL JOIN class c ON s.class_id = c.id;-- MySQL中模拟FULL JOIN
SELECT s.id, s.name, s.age, c.class_name, c.teacher
FROM student s
LEFT JOIN class c ON s.class_id = c.id
UNION
SELECT s.id, s.name, s.age, c.class_name, c.teacher
FROM student s
RIGHT JOIN class c ON s.class_id = c.id;
七、子查询
子查询是嵌套在其他SQL语句中的查询语句。
1. WHERE子句中的子查询
-- 查询年龄大于平均年龄的学生
SELECT * FROM student
WHERE age > (SELECT AVG(age) FROM student);-- 查询与张三同班的学生
SELECT * FROM student
WHERE class_id = (SELECT class_id FROM student WHERE name = '张三');
2. FROM子句中的子查询
-- 查询每个班级的学生人数和平均年龄
SELECT class_id, COUNT(*) AS 人数, AVG(age) AS 平均年龄
FROM (SELECT id, name, age, class_id FROM student
) AS temp_table
GROUP BY class_id;
3. IN子查询
-- 查询在计算机1班或软件1班的学生
SELECT * FROM student
WHERE class_id IN (SELECT id FROM class WHERE class_name IN ('计算机1班', '软件1班')
);
4. EXISTS子查询
-- 查询有学生的班级
SELECT * FROM class c
WHERE EXISTS (SELECT 1 FROM student s WHERE s.class_id = c.id
);
八、视图和索引
1. 视图(VIEW)
视图是基于查询结果的虚拟表,可以简化复杂查询。
-- 创建视图
CREATE VIEW student_class_info AS
SELECT s.id, s.name, s.age, c.class_name, c.teacher
FROM student s
JOIN class c ON s.class_id = c.id;-- 使用视图
SELECT * FROM student_class_info;-- 修改视图
ALTER VIEW student_class_info AS
SELECT s.id, s.name, s.age, s.gender, c.class_name, c.teacher
FROM student s
JOIN class c ON s.class_id = c.id;-- 删除视图
DROP VIEW student_class_info;
2. 索引(INDEX)
索引可以提高查询速度,但会减慢写入操作。
-- 创建索引
CREATE INDEX idx_student_name ON student(name);-- 创建复合索引
CREATE INDEX idx_student_class_age ON student(class_id, age);-- 查看索引
SHOW INDEX FROM student;-- 删除索引
DROP INDEX idx_student_name ON student;
九、事务处理
事务是一组原子性的SQL操作,要么全部成功,要么全部失败。
-- 开始事务
START TRANSACTION;-- 执行SQL操作
UPDATE account SET balance = balance - 100 WHERE id = 1;
UPDATE account SET balance = balance + 100 WHERE id = 2;-- 提交事务(确认操作)
COMMIT;-- 或者回滚事务(取消操作)
-- ROLLBACK;
事务的四个特性(ACID):
- 原子性(Atomicity):事务是一个不可分割的工作单位
- 一致性(Consistency):事务前后数据的完整性必须保持一致
- 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务
- 持久性(Durability):事务一旦提交,其结果应该永久保存在数据库中
十、SQL注入防护
SQL注入是一种常见的安全漏洞,初学者必须了解如何防护。
1. 什么是SQL注入?
假设用户输入:
' OR '1'='1'
如果直接拼接到SQL中:
SELECT * FROM users WHERE username = '$username' AND password = '$password';
会变成:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '';
这会返回所有用户记录!
2. 如何防止SQL注入?
使用参数化查询(预处理语句):
// PHP中的参数化查询示例
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username AND password = :password");
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$stmt->execute();
其他防护措施:
- 过滤用户输入
- 限制数据库用户权限
- 使用ORM框架
- 对敏感信息加密
十一、SQL常用函数
1. 字符串函数
-- 字符串长度
SELECT LENGTH('Hello World'); -- 结果: 11-- 字符串拼接
SELECT CONCAT('Hello', ' ', 'World'); -- 结果: 'Hello World'-- 大小写转换
SELECT UPPER('hello'); -- 结果: 'HELLO'
SELECT LOWER('WORLD'); -- 结果: 'world'-- 截取字符串
SELECT SUBSTRING('Hello World', 1, 5); -- 结果: 'Hello'-- 去除空格
SELECT TRIM(' Hello World '); -- 结果: 'Hello World'
2. 日期函数
-- 获取当前日期和时间
SELECT NOW(); -- 例如: 2023-04-15 14:30:45
SELECT CURDATE(); -- 例如: 2023-04-15
SELECT CURTIME(); -- 例如: 14:30:45-- 日期格式化
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d'); -- 例如: '2023-04-15'
SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日 %H:%i:%s'); -- 例如: '2023年04月15日 14:30:45'-- 日期计算
SELECT DATE_ADD(NOW(), INTERVAL 1 DAY); -- 明天此时
SELECT DATE_SUB(NOW(), INTERVAL 1 WEEK); -- 上周此时
SELECT DATEDIFF('2023-12-31', '2023-01-01'); -- 日期差,结果: 364
3. 数学函数
-- 绝对值
SELECT ABS(-10); -- 结果: 10-- 四舍五入
SELECT ROUND(3.14159); -- 结果: 3
SELECT ROUND(3.14159, 2); -- 结果: 3.14(保留2位小数)-- 向上取整和向下取整
SELECT CEIL(3.1); -- 结果: 4
SELECT FLOOR(3.9); -- 结果: 3-- 随机数
SELECT RAND(); -- 生成0-1之间的随机数
SELECT FLOOR(1 + (RAND() * 100)); -- 生成1-100之间的随机整数
十二、SQL实用示例
1. 学生成绩管理系统示例
创建表:
-- 创建学生表
CREATE TABLE students (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,gender VARCHAR(10),birthday DATE
);-- 创建课程表
CREATE TABLE courses (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,credit INT
);-- 创建成绩表
CREATE TABLE scores (id INT PRIMARY KEY AUTO_INCREMENT,student_id INT,course_id INT,score FLOAT,FOREIGN KEY (student_id) REFERENCES students(id),FOREIGN KEY (course_id) REFERENCES courses(id)
);
插入示例数据:
-- 插入学生
INSERT INTO students (name, gender, birthday) VALUES
('张三', '男', '2000-01-15'),
('李四', '女', '2000-03-22'),
('王五', '男', '1999-12-10');-- 插入课程
INSERT INTO courses (name, credit) VALUES
('数学', 4),
('英语', 3),
('计算机基础', 5);-- 插入成绩
INSERT INTO scores (student_id, course_id, score) VALUES
(1, 1, 85), (1, 2, 92), (1, 3, 88),
(2, 1, 78), (2, 2, 88), (2, 3, 95),
(3, 1, 92), (3, 2, 80), (3, 3, 85);
查询示例:
-- 查询所有学生的所有课程成绩
SELECT s.name, c.name AS course_name, sc.score
FROM students s
JOIN scores sc ON s.id = sc.student_id
JOIN courses c ON sc.course_id = c.id
ORDER BY s.name, c.name;-- 查询每个学生的平均成绩
SELECT s.name, AVG(sc.score) AS average_score
FROM students s
JOIN scores sc ON s.id = sc.student_id
GROUP BY s.name
ORDER BY average_score DESC;-- 查询每门课程的最高分、最低分和平均分
SELECT c.name, MAX(sc.score) AS max_score, MIN(sc.score) AS min_score, AVG(sc.score) AS avg_score
FROM courses c
JOIN scores sc ON c.id = sc.course_id
GROUP BY c.name;-- 查询挂科(成绩<60)的学生信息
SELECT s.name, c.name AS course_name, sc.score
FROM students s
JOIN scores sc ON s.id = sc.student_id
JOIN courses c ON sc.course_id = c.id
WHERE sc.score < 60
ORDER BY c.name, s.name;
2. 分页查询示例
-- 每页显示10条数据,查询第3页
SELECT * FROM student
ORDER BY id ASC
LIMIT 20, 10;-- 计算公式:(页码-1)*每页条数, 每页条数
3. 数据导入导出示例
MySQL导出数据:
-- 导出整个数据库
mysqldump -u用户名 -p 数据库名 > 导出文件名.sql-- 导出特定表
mysqldump -u用户名 -p 数据库名 表名 > 导出文件名.sql
MySQL导入数据:
-- 导入数据库
mysql -u用户名 -p 数据库名 < 导入文件名.sql
十三、学习建议
- 从基础开始:先掌握SELECT、INSERT、UPDATE、DELETE等基础语句
- 多练习:找一个在线SQL练习平台,如SQLZoo、W3Schools等,多做练习题
- 理解关系模型:掌握主键、外键、索引等概念
- 学习优化:了解如何优化SQL查询性能
- 了解不同数据库的特性:虽然基础SQL相似,但不同数据库有自己的扩展和特性
通过不断学习和实践,你将逐渐掌握SQL这门强大的数据库语言!
祝您学习愉快,早日成为SQL高手!