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

文章目录

    • 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
)
BEGININSERT 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
BEGINDECLARE 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.mzph.cn/pingmian/24649.shtml

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

相关文章

React Native 之 expo-cli使用 (二十四)

expo-cli是用于创建、运行和部署Universal Expo和React Native应用程序的工具。 1. 安装expo-cli 命令行或终端中运行以下命令来全局安装expo-cli: npm install -g expo-cli # 或者使用yarn yarn global add expo-cli//安装完成后,你可以通过运行ex…

什么是(RAG)检索增强生成?

检索增强生成(Retrieval-Augmented Generation) 在人工智能领域,生成式模型(Generative Models)如语言模型(Language Models, LMs),能够根据给定的输入生成连贯且有意义的文本。然而…

读取文件

自学python如何成为大佬(目录):自学python如何成为大佬(目录)_利用python语言智能手机的默认语言实战一-CSDN博客 在Python中打开文件后,除了可以向其写入或追加内容,还可以读取文件中的内容。读取文件内容主要分为以下几种情况: 1 读取指…

react 基础样式的控制(行内和className)

import ./index.cssconst style{color:red,font-size:150px }function App() {return (<div className"App"><h1>行内样式控制</h1><h1 style{{color:red,font-size:150px}} >asd </h1><span style{style} >asd </span>&l…

Docker——容器技术的发展

容器技术发展史 一、Jail时代 ​ 1979年&#xff0c;贝尔实验室发明了chroot&#xff1b;当一个系统软件编译完成之后&#xff0c;整个测试环境的变量便会发生变化&#xff1b;chroot就是将一个进程的文件系统进行隔离&#xff0c;将不同进程的的根目录发生改变&#xff1b;这…

Markdown入门语法笔记

Markdown入门语法笔记 引言 Markdown是一种轻量级的文本标记语言&#xff0c;基于“内容才是本质”的理念进行设计&#xff0c;排版格式简洁自然&#xff0c;让创作者将更多时间集中在内容创作而非排版上。Markdown在当今世界上应用非常广泛&#xff0c;论文排版、说明文档、…

2024年跨平台应用解决方法

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 很久没有写这类high-level的文章了,本身这类框架就一直层出不穷,但是其中历久弥坚,坚韧不拔的框架又有多少呢? 首先考虑到学习成本以及掌握一些编程语言在工作、学习生态上的价值,给这些东西适用生态划分一下. Reac…

tippecanoe-enumerate解释解释和使用示例

tippecanoe-enumerate 是 Tippecanoe 工具集中的一个实用命令,用于枚举和显示 MBTiles 文件中的所有瓦片信息。它可以帮助您查看和验证 MBTiles 文件中包含的瓦片数量、缩放级别、坐标等详细信息。这对于了解数据的分布和结构非常有用。 主要功能 枚举瓦片:列出 MBTiles 文件…

CentOS7 MySQL5.7.35主从 不停机搭建 以及配置

如需安装MySQL&#xff0c;参照MySQL 5.7.35 安装教程 https://blog.csdn.net/CsethCRM/article/details/119418841一、主&从 环境信息准备 1.1.查看硬盘信息&#xff0c;确保磁盘够用&#xff08;主&从&#xff09; df -h1.2.查看内存信息 &#xff08;主&从&am…

Ansible——cron模块

目录 参数总结 示例1&#xff1a;创建一个定时任务 示例2&#xff1a;删除一个定时任务 示例3&#xff1a;每周一早上 3 点清理临时文件 示例4&#xff1a;每小时运行一次日志轮转 示例5&#xff1a;为指定用户添加一个定时任务 Playbook (YAML 格式) 中管理定时任务。 …

elasticsearch安装与使用(4)-搜索入门

1、创建索引 PUT /hotel {"mappings": {"properties":{"title":{"type": "text"},"city":{"type": "keyword"},"price":{"type":"double"}}} }2、写入文档 …

sentaurus修改界面字体

修改界面字体&#xff0c;view——table options——change table 在出现的选框中选择使用系统默认或者自定义字体

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

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

代码随想录算法训练营第36期DAY49

DAY49 139单词拆分 没有思路。 回溯法 回溯怎么做呢&#xff1a;拼接str&#xff0c;看能不能拼出来。注意每个单词能用多次&#xff0c;不是用了就没。 但是语法还是难写。 自己的思路不好&#xff0c;题解思路&#xff1a;枚举所有分割字符串&#xff0c;判断是否在字典…

力扣每日一题85:最大矩形

题目 困难 相关标签 相关企业 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵&#xff0c;找出只包含 1 的最大矩形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;matrix [["1","0","1","0",&q…

LeetCode-day06-3040. 相同分数的最大操作数目 II

LeetCode-day06-3040. 相同分数的最大操作数目 II 题目描述示例示例1&#xff1a;示例2&#xff1a; 思路代码 题目描述 给你一个整数数组 nums &#xff0c;如果 nums 至少 包含 2 个元素&#xff0c;你可以执行以下操作中的 任意 一个&#xff1a; 选择 nums 中最前面两个元…

使用 Django 和 MQTT 构建实时数据传输应用

文章目录 什么是 MQTT&#xff1f;Django 中的 MQTT结论 在现代的 Web 应用程序开发中&#xff0c;实时数据传输变得越来越重要。MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的发布/订阅消息传输协议&#xff0c;而 Django 是一个流行的 Pyt…

如何解决访问网站时IP被限制的问题?

在互联网上&#xff0c;用户可能会面临一个令人困扰的问题——当尝试访问某个特定的网站时&#xff0c;却发现自己的IP地址被该网站屏蔽。 IP地址被网站屏蔽是一个相对常见的现象&#xff0c;而导致这种情况的原因多种多样&#xff0c;包括恶意行为、违规访问等。本文将解释IP地…

Linux进程基本概念

基本概念 内核观点&#xff1a;担当分配系统资源&#xff08;CPU时间&#xff0c;内存&#xff09;的实体进程信息被放在一个叫做进程控制块的数据结构中&#xff0c;可以理解为进程属性的集合&#xff08;PCB&#xff09;在Linux中描述进程的结构体叫做task_structtask_struc…

qt自定义事件过滤器

以下是一个完整的示例&#xff0c;包括如何使用这个事件过滤器的步骤&#xff1a; 1. 定义事件过滤器类 你已经正确定义了 LostFocusFilter 类&#xff0c;这里是完整的定义&#xff1a; #include <QObject> #include <QEvent>class LostFocusFilter : public Q…