【CS.DB】从零到精通:这可能是全网最全面最强大的SQL入门教程

news2024/11/28 10:34:09

文章目录

    • 1. 什么是SQL?
      • 1.1 SQL的历史
        • 1.1.1 SQL的标准化过程
    • 2. SQL基础语法
      • 2.1 数据库操作
        • 2.1.1 创建数据库
        • 2.1.2 删除数据库
      • 2.2 表操作
        • 2.2.1 创建表
        • 2.2.2 删除表
        • 2.2.3 修改表
      • 2.3 数据操作
        • 2.3.1 插入数据
        • 2.3.2 更新数据
        • 2.3.3 删除数据
      • 2.4 查询数据
        • 2.4.1 基本查询
        • 2.4.2 条件查询
        • 2.4.3 排序查询
        • 2.4.4 聚合函数
    • 3. 高级SQL语法
      • 3.1 连接操作
        • 3.1.1 内连接
        • 3.1.2 左连接
        • 3.1.3 右连接
        • 3.1.4 全外连接
      • 3.2 子查询
        • 3.2.1 简单子查询
        • 3.2.2 相关子查询
      • 3.3 联合查询
      • 3.4 GROUP BY 详解
        • 3.4.1 GROUP BY 语法
        • 3.4.2 创建示例数据
        • 3.4.3 经典例子
          • 3.4.3.1 按产品分组计算总销售数量
          • 3.4.3.2 按日期分组计算总销售数量
          • 3.4.3.3 按产品和日期分组计算总销售数量
      • 3.5 HAVING 子句
        • 3.5.1 使用 HAVING 进行过滤
        • 3.5.2 举例: 销售数据分析
          • 3.6.1.1 计算每个客户的总订单金额
          • 3.6.1.2 计算每个月的总销售额
          • 3.6.1.3 查找总订单金额超过1000的客户
    • 4. 数据完整性与约束
      • 4.1 主键约束
      • 4.2 外键约束
      • 4.3 唯一约束
      • 4.4 检查约束
    • 5. SQL函数
      • 5.1 字符串函数
      • 5.2 数学函数
      • 5.3 日期函数
    • 6. 视图
      • 6.1 创建视图
      • 6.2 查询视图
      • 6.3 删除视图
    • 7. 存储过程与函数
      • 7.1 创建存储过程
      • 7.2 调用存储过程
      • 7.3 创建函数
      • 7.4 调用函数
    • 8. 事务
      • 8.1 开始事务
      • 8.2 提交事务
      • 8.3 回滚事务
    • 9. SQL性能优化
      • 9.1 索引
      • 9.2 查询优化
      • 9.3 数据库设计优化
    • 10. SQL安全性
      • 10.1 用户权限管理
      • 10.2 数据加密
    • 11. 常见SQL错误与调试
      • 11.1 语法错误
      • 11.2 数据类型错误
      • 11.3 约束违反错误
    • 12. SQL工具与资源
      • 12.1 SQL客户端工具
      • 12.2 在线学习资源
      • 12.3 书籍推荐

在这里插入图片描述

1. 什么是SQL?

SQL(结构化查询语言)是一种用于管理和操作关系数据库的标准语言。它用于查询、更新、插入和删除数据库中的数据。

1.1 SQL的历史

SQL由IBM在20世纪70年代开发,并于1986年被美国国家标准协会(ANSI)采纳为标准。

1.1.1 SQL的标准化过程
  • 1970年:E.F. Codd提出关系数据库模型。
  • 1974年:IBM开始开发SQL。
  • 1986年:ANSI采纳SQL为标准。

2. SQL基础语法

2.1 数据库操作

2.1.1 创建数据库
CREATE DATABASE mydatabase;
2.1.2 删除数据库
DROP DATABASE mydatabase;

2.2 表操作

2.2.1 创建表
CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    birth_date DATE,
    hire_date DATE
);
2.2.2 删除表
DROP TABLE employees;
2.2.3 修改表
ALTER TABLE employees ADD COLUMN email VARCHAR(100);
ALTER TABLE employees DROP COLUMN email;

2.3 数据操作

2.3.1 插入数据
INSERT INTO employees (employee_id, first_name, last_name, birth_date, hire_date)
VALUES (1, 'John', 'Doe', '1980-01-01', '2020-01-01');
2.3.2 更新数据
UPDATE employees SET email = 'john.doe@example.com' WHERE employee_id = 1;
2.3.3 删除数据
DELETE FROM employees WHERE employee_id = 1;

2.4 查询数据

2.4.1 基本查询
SELECT * FROM employees;
2.4.2 条件查询
SELECT * FROM employees WHERE last_name = 'Doe';
2.4.3 排序查询
SELECT COUNT(*) FROM employees;
SELECT AVG(salary) FROM employees;
SELECT MAX(salary) FROM employees;
SELECT MIN(salary) FROM employees;
2.4.4 聚合函数
SELECT COUNT(*) FROM employees;
SELECT AVG(salary) FROM employees;
SELECT MAX(salary) FROM employees;
SELECT MIN(salary) FROM employees;

3. 高级SQL语法

3.1 连接操作

3.1.1 内连接

内连接用于返回两个表中存在匹配关系的行。

假设我们有两个表employeesdepartments,如下所示:

表:employees

employee_idfirst_namelast_namedepartment_id
1JohnDoe1
2JaneSmith2
3MikeJohnson3
4ChrisLeeNULL

表:departments

department_iddepartment_name
1HR
2Finance
3IT
4Marketing

内连接查询:

SELECT employees.first_name, departments.department_name
FROM employees
INNER JOIN departments ON employees.department_id = departments.department_id;

结果:

first_namedepartment_name
JohnHR
JaneFinance
MikeIT

解释: 内连接返回两个表中匹配关系的行。因为Chris的department_id为NULL,没有匹配的部门,所以不包含在结果中。

3.1.2 左连接

左连接返回左表中的所有行,即使在右表中没有匹配的行。

左连接查询:

SELECT employees.first_name, departments.department_name
FROM employees
LEFT JOIN departments ON employees.department_id = departments.department_id;

结果:

first_namedepartment_name
JohnHR
JaneFinance
MikeIT
ChrisNULL

解释: 左连接返回employees表中的所有行,并从departments表中返回匹配的行。如果没有匹配,则返回NULL。因此,Chris仍然包含在结果中,但没有匹配的部门。

3.1.3 右连接

右连接返回右表中的所有行,即使在左表中没有匹配的行。

右连接查询:

SELECT employees.first_name, departments.department_name
FROM employees
RIGHT JOIN departments ON employees.department_id = departments.department_id;

结果:

first_namedepartment_name
JohnHR
JaneFinance
MikeIT
NULLMarketing

解释: 右连接返回departments表中的所有行,并从employees表中返回匹配的行。如果没有匹配,则返回NULL。在这个例子中,新增的Marketing部门没有对应的员工,所以显示为NULL。其余匹配的行显示对应的员工和部门。

通过这个例子,我们可以清楚地看到右连接的作用。即使employees表中没有匹配的记录,右连接也会返回departments表中的所有行,并用NULL填充没有匹配的行。

Note: employees表的每个department_id都有匹配的部门,那么结果将与内连接相同。

3.1.4 全外连接

全外连接(FULL OUTER JOIN)用于返回左表和右表中的所有行。如果在另一表中没有匹配的行,则返回NULL。

全外连接查询:

SELECT employees.first_name, departments.department_name
FROM employees
FULL OUTER JOIN departments ON employees.department_id = departments.department_id;

结果:

first_namedepartment_name
JohnHR
JaneFinance
MikeIT
ChrisNULL
NULLMarketing

解释: 全外连接返回两个表中的所有行。如果在另一表中没有匹配的行,则返回NULL。此例中,Chris没有匹配的部门,因此department_name为NULL;Marketing没有匹配的员工,因此first_name为NULL。

3.2 子查询

3.2.1 简单子查询
SELECT first_name, last_name
FROM employees
WHERE department_id = (SELECT department_id FROM departments WHERE department_name = 'Sales');
3.2.2 相关子查询
SELECT first_name, last_name
FROM employees e
WHERE EXISTS (SELECT 1 FROM departments d WHERE d.department_id = e.department_id AND d.department_name = 'Sales');

3.3 联合查询

SELECT first_name, last_name FROM employees
UNION
SELECT first_name, last_name FROM managers;

3.4 GROUP BY 详解

3.4.1 GROUP BY 语法

GROUP BY 语句用于根据一个或多个列对结果集进行分组。通常与聚合函数(如COUNTSUMAVGMAXMIN等)一起使用,以对每个组执行计算。

基本语法:

SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE condition
GROUP BY column_name;
3.4.2 创建示例数据

首先,我们创建一个名为sales的示例表,并插入一些数据:

CREATE TABLE sales (
    sale_id INT,
    product VARCHAR(50),
    quantity INT,
    sale_date DATE
);

INSERT INTO sales (sale_id, product, quantity, sale_date) VALUES
(1, 'Apple', 10, '2024-06-01'),
(2, 'Banana', 5, '2024-06-01'),
(3, 'Apple', 8, '2024-06-02'),
(4, 'Banana', 7, '2024-06-02'),
(5, 'Apple', 12, '2024-06-03'),
(6, 'Banana', 3, '2024-06-03');
3.4.3 经典例子
3.4.3.1 按产品分组计算总销售数量
SELECT product, SUM(quantity) AS total_quantity
FROM sales
GROUP BY product;

此查询按product列分组,并计算每种产品的总销售数量。结果如下:

producttotal_quantity
Apple30
Banana15
3.4.3.2 按日期分组计算总销售数量
SELECT sale_date, SUM(quantity) AS total_quantity
FROM sales
GROUP BY sale_date;

此查询按sale_date列分组,并计算每个日期的总销售数量。结果如下:

sale_datetotal_quantity
2024-06-0115
2024-06-0215
2024-06-0315
3.4.3.3 按产品和日期分组计算总销售数量
SELECT product, sale_date, SUM(quantity) AS total_quantity
FROM sales
GROUP BY product, sale_date;

此查询按productsale_date列分组,并计算每种产品在每个日期的总销售数量。结果如下:

productsale_datetotal_quantity
Apple2024-06-0110
Apple2024-06-028
Apple2024-06-0312
Banana2024-06-015
Banana2024-06-027
Banana2024-06-033

3.5 HAVING 子句

HAVING 子句用于在分组后的结果集上进行过滤,与GROUP BY一起使用。它的作用类似于WHERE,但WHERE子句作用于分组前的行,而HAVING子句作用于分组后的结果。

SELECT product, SUM(quantity) AS total_quantity
FROM sales
GROUP BY product
HAVING SUM(quantity) > 15;
3.5.1 使用 HAVING 进行过滤

此查询按product列分组,并计算每种产品的总销售数量。然后,过滤出总销售数量大于15的产品。结果如下:

producttotal_quantity
Apple30
3.5.2 举例: 销售数据分析

假设我们有一个名为orders的表,包含以下字段:

ColumnDescription
order_id订单ID
customer_id客户ID
product_id产品ID
order_date订单日期
quantity订单数量
price订单价格(单价)

我们希望进行以下分析:

3.6.1.1 计算每个客户的总订单金额
SELECT customer_id, SUM(quantity * price) AS total_amount
FROM orders
GROUP BY customer_id;
3.6.1.2 计算每个月的总销售额
SELECT EXTRACT(YEAR_MONTH FROM order_date) AS month, SUM(quantity * price) AS total_sales
FROM orders
GROUP BY EXTRACT(YEAR_MONTH FROM order_date);
3.6.1.3 查找总订单金额超过1000的客户
SELECT customer_id, SUM(quantity * price) AS total_amount
FROM orders
GROUP BY customer_id
HAVING total_amount > 1000;

4. 数据完整性与约束

4.1 主键约束

CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50)
);

4.2 外键约束

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    employee_id INT,
    FOREIGN KEY (employee_id) REFERENCES employees(employee_id)
);

4.3 唯一约束

CREATE TABLE users (
    user_id INT PRIMARY KEY,
    email VARCHAR(100) UNIQUE
);

4.4 检查约束

CREATE TABLE products (
    product_id INT PRIMARY KEY,
    price DECIMAL(10, 2),
    CHECK (price > 0)
);

5. SQL函数

5.1 字符串函数

SELECT UPPER(first_name) FROM employees;
SELECT LOWER(last_name) FROM employees;
SELECT LENGTH(first_name) FROM employees;

5.2 数学函数

SELECT ABS(-10);
SELECT ROUND(price, 2) FROM products;
SELECT MOD(salary, 2) FROM employees;

5.3 日期函数

SELECT CURRENT_DATE;
SELECT EXTRACT(YEAR FROM birth_date) FROM employees;
SELECT DATE_ADD(hire_date, INTERVAL 1 YEAR) FROM employees;

6. 视图

6.1 创建视图

CREATE VIEW employee_view AS
SELECT first_name, last_name, department_name
FROM employees
JOIN departments ON employees.department_id = departments.department_id;

6.2 查询视图

SELECT * FROM employee_view;

6.3 删除视图

DROP VIEW employee_view;

7. 存储过程与函数

7.1 创建存储过程

CREATE PROCEDURE add_employee(
    IN first_name VARCHAR(50),
    IN last_name VARCHAR(50),
    IN birth_date DATE,
    IN hire_date DATE
)
BEGIN
    INSERT INTO employees (first_name, last_name, birth_date, hire_date)
    VALUES (first_name, last_name, birth_date, hire_date);
END;

7.2 调用存储过程

CALL add_employee('Jane', 'Smith', '1990-02-01', '2021-02-01');

7.3 创建函数

CREATE FUNCTION calculate_age(birth_date DATE) RETURNS INT
BEGIN
    DECLARE age INT;
    SET age = YEAR(CURRENT_DATE) - YEAR(birth_date);
    RETURN age;
END;

7.4 调用函数

SELECT calculate_age('1980-01-01');

8. 事务

8.1 开始事务

START TRANSACTION;

8.2 提交事务

COMMIT;

8.3 回滚事务

ROLLBACK;

9. SQL性能优化

9.1 索引

CREATE INDEX idx_last_name ON employees(last_name);

9.2 查询优化

  • 使用EXPLAIN分析查询计划
  • 避免SELECT *
  • 使用适当的联合和子查询
  • 优化索引使用

9.3 数据库设计优化

  • 规范化数据库设计
  • 使用适当的数据类型
  • 避免冗余数据

10. SQL安全性

10.1 用户权限管理

CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT, INSERT ON mydatabase.* TO 'username'@'localhost';
REVOKE INSERT ON mydatabase.* FROM 'username'@'localhost';

10.2 数据加密

  • 使用数据库自带的加密功能
  • 在应用层进行数据加密

11. 常见SQL错误与调试

11.1 语法错误

  • 错误示例:SELEC * FROM employees;
  • 调试方法:检查SQL关键字拼写,使用SQL编辑器的语法高亮功能

11.2 数据类型错误

  • 错误示例:INSERT INTO employees (employee_id, first_name) VALUES ('one', 'John');
  • 调试方法:确保数据类型匹配,使用CAST或CONVERT函数进行类型转换

11.3 约束违反错误

  • 错误示例:INSERT INTO employees (employee_id) VALUES (1); -- 重复的主键
  • 调试方法:检查表的约束条件,确保数据符合约束要求

12. SQL工具与资源

12.1 SQL客户端工具

  • MySQL Workbench
  • SQL Server Management Studio (SSMS)
  • DBeaver
  • HeidiSQL

12.2 在线学习资源

  • LeetCode SQL练习
  • SQLZoo

12.3 书籍推荐

  • 《SQL基础教程》 by Ben Forta
  • 《SQL必知必会》 by Ben Forta
  • 《SQL权威指南》 by Jonathan Gennick

#sql

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1802592.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】进程4——进程状态

1.进程状态 什么是状态? 每个人都有状态——颓废,阳光,积极向上。。。。 进程也有状态 在操作系统中,由于进程的数量是非常多的,而系统的资源又非常少,所以不可能每一个进程在每时每刻都会处于上处理机运…

【 技术栈】技术方案到底怎么写?

文章目录 一、背景二、技术方案重要性三、常见的技术方案有哪些内容1、系统用例2、功能整体链路2.1、核心业务流程 3、数据库设计4、接口设计5、非功能设计5.1、性能与稳定性5.2、监控 7、系统风险点评估 四、总结 一、背景 工作中,有一些需求或者技术改造&#xf…

计算机网络--应用层

计算机网络–计算机网络概念 计算机网络–物理层 计算机网络–数据链路层 计算机网络–网络层 计算机网络–传输层 计算机网络–应用层 1. 概述 因为不同的网络应用之间需要有一个确定的通信规则。 1.1 两种常用的网络应用模型 1.1.1 客户/服务器模型(Client/Se…

Java面试八股之什么是反射,实现原理是什么

Java中什么是反射,实现原理是什么 Java中的反射(Reflection)是一种强大的特性,它允许程序在运行时检查和操作类、接口、字段和方法的信息。简而言之,反射机制使得程序能够在运行时动态地了解和使用自身或其他程序集中…

python文件:py,ipynb, pyi, pyc, pyd, pyo都是什么文件?

1、Python文件类型介绍 📁 1.1 .py 文件:源代码基础 .py 文件是 Python 最基本的源代码文件格式,用于存储纯文本形式的 Python 代码。它是开发者编写程序的主要场所,包含函数、类、变量定义以及执行逻辑。Python 解释器直接读取…

【排序算法】总结篇

✨✨这些 排序算法都是指的 需要进行比较的排序算法 ✨✨下面都是略微讲解一下思路,如果需要详细了解哪一个排序,点击👉链接即可 ✨✨对于时间、空间复杂度、稳定性,希望你🧑‍🎓能够理解记忆🧑…

MyBatisPlus插件生成代码

文章目录 概要安装插件使用插件 概要 MyBatis-Plus 是 MyBatis 的增强工具,旨在简化 MyBatis 的开发。MyBatis-Plus 代码生成器插件可以自动生成项目中常见的代码,如实体类、Mapper 接口、Service 接口和实现类、Controller 等,从而减少手动…

python代码中参数的默认值

python中的函数,可以给形参指定默认值。 带有默认值的参数,可以在调用的时候不传参。 如上图所示,在给函数设定形参的时候可以给函数形参设定默认值,当然默认参数的形参应该在非默认形参的后面。 如果在调用函数的时候&#xff…

SpringBoot整合SpringSecurit(二)通过token进行访问

在文章:SpringBoot整合SpringSecurit(一)实现ajax的登录、退出、权限校验-CSDN博客 里面,使用的session的方式进行保存用户信息的,这一篇文章就是使用token的方式。 在其上进行的改造,可以先看SpringBoot…

ctfshow-web入门-命令执行(web41_exp与分析)

过滤不严,命令执行 preg_match(/[0-9]|[a-z]|\^|\|\~|\$|\[|\]|\{|\}|\&|\-/i, $c) 过滤掉了数字、字母以及一些符号,之前接触过的无字母 rce 是取反编码再取反,采用不可见字符去绕过正则,但是这里取反符号被过滤掉了&#x…

还在为线上BUG苦苦找寻?试试IntelliJ IDEA远程调试线上Java程序

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…

VMware导入小白分享的MacOS版本之后,无法开机的解决方案

前言 这段时间陆续有小伙伴找到小白,说:导入小白分享的MacOS版本之后,出现无法开机的问题。 遇到这个问题,并不是说明分享版本有问题,因为大部分小伙伴导入之后都没有出现类似的问题,都是导入之后开机&…

VBA经典应用69例应用5:使用VBA冻结窗格

《VBA经典应用69例》(版权10178981),是我推出的第九套教程,教程是专门针对初级、中级学员在学习VBA过程中可能遇到的案例展开,这套教程案例众多,紧贴“实战”,并做“战术总结”,以便…

PaddleSpeech MFA:阿米娅中文音色复刻计划

PaddleSpeech:阿米娅中文音色复刻计划 本篇项目是对iterhui大佬项目[PaddleSpeech 原神] 音色克隆之胡桃的复刻,使用的PaddleSpeech的版本较新,也针对新版本的PaddleSpeech做了许多配置之上的更新并加入了自己对语音的对齐、配置、训练其它任…

Buildroot和Debian文件系统修改方法

本文档主要介绍在没有编译环境的情况下,如何修改buildroot和debian文件系统方法,如在buildroot文件系统中添加文件、修改目录等文件操作,在debian文件系统中,安装软件库、工具、扩大文件系统空间等等操作。 1.Debian文件系统 …

Java | Leetcode Java题解之第137题只出现一次的数字II

题目: 题解: class Solution {public int singleNumber(int[] nums) {int a 0, b 0;for (int num : nums) {b ~a & (b ^ num);a ~b & (a ^ num);}return b;} }

AndroidStudio无法识别连接夜神模拟器

方法一(无法从根本上解决) ①进入夜神模拟器安装路径下的bin路径(安装路径可以带有中文路径) ②打开cmd窗口,输入以下代码(一定要打开模拟器) nox_adb.exe connect 127.0.0.1:62001 方法二(根本上解决) 原因:Android Studio的adb版本与夜神模拟器的adb版本不一致 ①打开And…

【Unity】 HTFramework框架(五十一)代码片段执行器

更新日期:2024年6月8日。 Github源码:[点我获取源码] Gitee源码:[点我获取源码] 索引 Code Snippet Executer 代码片段执行器使用 Code Snippet Executer打开 Code Snippet Executer动态执行(代码片段)静态执行&#x…

core dump核心转储

检查核心转储是否开启&#xff0c;否则无法生成core文件 ulimit -a 如果为0就需要修改 ulimit -c 10240 写一个会触发core命令的程序 以浮点数运算为例 #include <iostream>int main() {int i 1/0; } 在编译时使用-g选项 运行程序&#xff0c;生成core文件 gdb调试 g…

本地部署GLM-4-9B清华智谱开源大模型方法和对话效果体验

GLM-4-9B是清华大学和智谱AI推出的最新一代预训练模型GLM-4系列中的开源版本。在语义、数学、推理、代码和知识等多方面的数据集测评中&#xff0c;GLM-4-9B及其人类偏好对齐的版本GLM-4-9B-Chat均表现出较高的性能&#xff0c;其通用能力评测结果甚至超越了Llama-3-8B开源大模…