写在前面!!!SQL 学习黄金法则:
核心原则:理解优先,实践至上,思考,持续积累。
基础概念
1. 数据库 (Database): 组织数据的集合,包含多个表、视图、存储过程等对象。可以将其理解为一个容器,用于存放和管理相关的数据。
3. 字段 (Field/Column): 表中的一列,代表数据的某个特定属性。例如,“客户”表中的“姓名”字段存储客户的姓名信息。每个字段都有特定的数据类型,例如整数、文本、日期等。
4. 数据类型 (Data Type): 定义字段中可以存储的数据的类型。常见的数据类型包括:
* INT 或 INTEGER: 整数
* VARCHAR: 变长字符串
* DATE: 日期
* DATETIME: 日期和时间
* DECIMAL 或 NUMERIC: 定点数
* BOOLEAN: 布尔值 (真或假)
5. 主键 (Primary Key): 表中用于唯一标识每一行的字段或字段组合。主键不能为空,且值必须唯一。例如,“客户”表中的“客户ID”可以作为主键。
6. 外键 (Foreign Key): 一个表中的字段,引用另一个表的主键。用于建立表之间的关系。例如,“订单”表中的“客户ID”可以作为外键,引用“客户”表中的“客户ID”。
8. 视图 (View): 基于一个或多个表的虚拟表。视图不存储实际数据,而是根据定义的查询语句动态生成数据。可以简化复杂的查询,提高数据安全性。
9. 存储过程 (Stored Procedure): 预编译的 SQL 代码块,可以重复使用。可以提高数据库性能,简化数据库操作。
10. 事务 (Transaction): 一系列数据库操作,被视为一个单元。要么全部成功执行,要么全部回滚,保证数据的一致性。
11. SQL 语句分类: SQL 语句主要分为以下几类:
* DDL (Data Definition Language): 数据定义语言,用于创建、修改和删除数据库对象,例如 CREATE, ALTER, DROP。
* DML (Data Manipulation Language): 数据操作语言,用于查询和修改数据,例如 SELECT, INSERT, UPDATE, DELETE。
* DCL (Data Control Language): 数据控制语言,用于控制数据库访问权限,例如 GRANT, REVOKE。
13. 架构:服务器内部的数据库架构,如同文件夹,用于组织不同用途的数据表,常见的架构有 ODS、EDW、EDW_S 和 DDM。ODS (操作型数据仓库) 同步所有业务数据,比 EDW 更详细但也更复杂冗余。EDW (企业级数据仓库) 存储处理汇总后的数据,可供业务直接使用,EDW_S 则是安全级别更高的企业级数据库。DDM (分布式数据库中间件) 是针对特定应用或需求构建的局部数据库,只关注自身所需数据,可基于数据仓库或建设。
通过实际业务场景学习SQL基础语法
0. 数据准备
首先创建我们需要的相关表:
-- 创建门店表
CREATE TABLE stores (
store_id INT PRIMARY KEY,
store_name VARCHAR(50),
brand_name VARCHAR(50),
city VARCHAR(20),
status VARCHAR(10)
);
-- 创建销售数据表
CREATE TABLE sales (
id INT PRIMARY KEY AUTO_INCREMENT,
store_id INT,
platform VARCHAR(20),
sale_date DATE,
gmv DECIMAL(10,2),
order_count INT,
customer_count INT
);
-- 创建广告消耗表
CREATE TABLE advertising (
id INT PRIMARY KEY AUTO_INCREMENT,
store_id INT,
platform VARCHAR(20),
ad_date DATE,
cpc_cost DECIMAL(10,2)
);
-- 插入一些测试数据
INSERT INTO stores VALUES
(1, '北京朝阳店', '老鸭粉丝', '北京', 'active'),
(2, '上海徐家汇店', '老鸭粉丝', '上海', 'active'),
(3, '深圳南山店', '川味小馆', '深圳', 'active');
-- 更多测试数据...
1. 查看表结构
-- 场景:刚来公司第一天,查看门店营业表结构
DESCRIBE stores;
DESCRIBE sales;
DESCRIBE advertising;
-- 或者使用更详细的命令
SHOW CREATE TABLE stores;
2. 基础查询(SELECT & FROM & WHERE)
-- 场景:运营需要查看旗下所有品牌和门店12月1日至7日在美团上的GMV和下单量
SELECT
s.store_id,
st.store_name,
st.brand_name,
s.sale_date,
s.gmv,
s.order_count
FROM sales s
JOIN stores st ON s.store_id = st.store_id
WHERE s.platform = '美团'
AND s.sale_date BETWEEN '2023-12-01' AND '2023-12-07';
3. 表连接(JOIN)
-- 场景:查询所有门店每天的GMV和CPC消耗
SELECT
s.sale_date,
st.store_name,
st.brand_name,
s.gmv,
COALESCE(a.cpc_cost, 0) as cpc_cost,
ROUND(s.gmv / NULLIF(a.cpc_cost, 0), 2) as roi
FROM sales s
JOIN stores st ON s.store_id = st.store_id
LEFT JOIN advertising a ON s.store_id = a.store_id
AND s.sale_date = a.ad_date
AND s.platform = a.platform
WHERE s.sale_date >= '2023-12-01';
4. 分组统计(GROUP BY)
-- 场景:查看旗下所有品牌各门店12月1日至7日期间在所有平台上的总GMV和总下单人数
SELECT
st.brand_name,
st.store_name,
SUM(s.gmv) as total_gmv,
COUNT(DISTINCT s.customer_count) as total_customers,
COUNT(DISTINCT s.sale_date) as active_days
FROM sales s
JOIN stores st ON s.store_id = st.store_id
WHERE s.sale_date BETWEEN '2023-12-01' AND '2023-12-07'
GROUP BY st.brand_name, st.store_name;
5. 分组筛选(HAVING)
-- 场景:只看累计GMV在3万以上,并且下单人数在200人以上的门店
SELECT
st.store_name,
st.brand_name,
SUM(s.gmv) as total_gmv,
COUNT(DISTINCT s.customer_count) as total_customers
FROM sales s
JOIN stores st ON s.store_id = st.store_id
WHERE s.sale_date BETWEEN '2023-12-01' AND '2023-12-07'
GROUP BY st.store_name, st.brand_name
HAVING total_gmv >= 30000
AND total_customers >= 200
ORDER BY total_gmv DESC;
6. 排序和(ORDER BY & LIMIT)
-- 场景:对表格进行排序,显示指定行数的数据
SELECT
st.store_name,
s.sale_date,
s.gmv,
s.order_count,
ROUND(s.gmv / s.order_count, 2) as avg_order_value
FROM sales s
JOIN stores st ON s.store_id = st.store_id
WHERE s.sale_date >= '2023-12-01'
ORDER BY s.gmv DESC
LIMIT 10;
7. 窗口函数
-- 场景:查询2020年在饿了么平台下每个门店GMV最高那天的日期和GMV
WITH daily_sales AS (
SELECT
st.store_name,
s.sale_date,
s.gmv,
RANK() OVER(PARTITION BY s.store_id ORDER BY s.gmv DESC) as gmv_rank
FROM sales s
JOIN stores st ON s.store_id = st.store_id
WHERE s.platform = '饿了么'
AND YEAR(s.sale_date) = 2020
)
SELECT
store_name,
sale_date,
gmv
FROM daily_sales
WHERE gmv_rank = 1;
8. 实用技巧
8.1 日期处理
-- 获取最近30天数据
WHERE sale_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
-- 按月份统计
SELECT
DATE_FORMAT(sale_date, '%Y-%m') as month,
SUM(gmv) as monthly_gmv
FROM sales
GROUP BY DATE_FORMAT(sale_date, '%Y-%m');
8.2 数值计算
-- 计算环比增长
WITH monthly_sales AS (
SELECT
DATE_FORMAT(sale_date, '%Y-%m') as month,
SUM(gmv) as monthly_gmv
FROM sales
GROUP BY DATE_FORMAT(sale_date, '%Y-%m')
)
SELECT
month,
monthly_gmv,
LAG(monthly_gmv) OVER(ORDER BY month) as prev_month_gmv,
ROUND((monthly_gmv - LAG(monthly_gmv) OVER(ORDER BY month))
/ LAG(monthly_gmv) OVER(ORDER BY month) * 100, 2) as growth_rate
FROM monthly_sales;
9. SQL执行顺序
记住SQL的执行顺序很重要:
- FROM/JOIN:确定数据来源
- WHERE:行级过滤
- GROUP BY:分组聚合
- HAVING:组级过滤
- SELECT:选择/计算字段
- ORDER BY:排序
- LIMIT:返回行数
10. 练习题
- 统计每个品牌的日均GMV
- 查找每个门店订单量最高的三天
- 计算所有门店的月度环比增长率
- 分析不同平台的获客成本(GMV/CPC)
小贴士:
- 写复杂查询时,先写框架后填充:
SELECT -- 字段
FROM -- 主表
JOIN -- 关联
WHERE -- 条件
GROUP BY -- 分组
HAVING -- 分组筛选
ORDER BY -- 排序
LIMIT --
- 使用WITH子句提高代码可读性
- 养成写注释的好习惯
- 复杂查询多用临时表测试
记得点赞关注!✨