Skip to content

商务SQL精简

一份按课程模块组织的SQL关键概念快速参考指南。

1. 🔍 SQL基础

1.1 数据库:超级Excel工作簿

关键对比:

Excel术语SQL/数据库术语
工作表/表格表(Table)
列/字段(Column/Field)
记录(Record)
工作簿数据库(Database)

为什么使用数据库?

  • 可处理数百万行数据
  • 分析速度更快
  • 支持多用户访问
  • 更好的数据完整性

Excel与SQL任务对比:

Excel操作SQL等效操作
筛选行WHERE子句
选择列SELECT语句
数据排序ORDER BY子句
计算列SELECT中的表达式
数据透视表GROUP BY聚合

1.2 第一个SELECT语句

基本语法:

sql
SELECT * FROM table_name;

关键点:

  • SELECT * 检索所有列
  • FROM 指定要查询的表
  • 相当于在Excel中打开一个工作表

示例:

sql
SELECT * FROM sales;

返回结果:

SaleDateProductAmount
2024-05-01Apples120
2024-05-01Oranges80

1.3 选择特定列

基本语法:

sql
SELECT column1, column2 FROM table_name;

列别名:

sql
SELECT column1 AS alias1, column2 AS alias2 FROM table_name;

关键点:

  • 在SELECT后列出用逗号分隔的列
  • 使用AS为结果中的列重命名
  • 查询中列的顺序决定输出顺序

示例:

sql
SELECT Product, Amount FROM sales;

返回结果:

ProductAmount
Apples120
Oranges80
sql
SELECT Product AS 商品, Amount AS 总金额 FROM sales;

返回结果:

商品总金额
Apples120
Oranges80

2. ⚙️ 数据筛选

2.1 WHERE: SQL筛选器

基本语法:

sql
SELECT columns FROM table_name
WHERE condition;

比较运算符:

运算符含义示例
=等于Product = 'Apples'
<>不等于Product <> 'Oranges'
>大于Amount > 100
<小于Amount < 100
>=大于等于Amount >= 100
<=小于等于Amount <= 100

NULL处理:

sql
WHERE column IS NULL
WHERE column IS NOT NULL

COALESCE示例:

sql
SELECT *, COALESCE(Amount, 0) AS Amount_Defaulted
FROM sales
WHERE COALESCE(Amount, 0) > 100;

关键点:

  • WHERE根据条件筛选行
  • 使用IS NULL/IS NOT NULL检查NULL值
  • COALESCE为NULL值提供默认值

2.2 数字和范围筛选

范围筛选:

sql
WHERE column BETWEEN value1 AND value2

多值筛选:

sql
WHERE column IN (value1, value2, ...)

组合条件:

sql
WHERE condition1 AND condition2
WHERE condition1 OR condition2

示例:

sql
SELECT * FROM sales
WHERE Amount BETWEEN 80 AND 120;
sql
SELECT * FROM sales
WHERE Product IN ('Apples', 'Oranges');
sql
SELECT * FROM sales
WHERE Product = 'Apples' AND Amount > 100;

关键点:

  • BETWEEN包含两个端点值
  • IN匹配列表中的任何值
  • AND/OR组合多个条件

2.3 使用LIKE进行文本搜索

模式匹配:

sql
WHERE column LIKE '%pattern%'

通配符:

  • % 匹配任意数量字符
  • _ 匹配单个字符

示例:

sql
-- 包含"App"
WHERE Product LIKE '%App%'

-- 以"App"开头
WHERE Product LIKE 'App%'

-- 以"es"结尾
WHERE Product LIKE '%es'

-- 不区分大小写搜索
WHERE LOWER(Product) LIKE '%app%'

关键点:

  • LIKE支持灵活的文本模式匹配
  • 类似于Excel的"包含"筛选
  • 使用LOWER()进行不区分大小写搜索

2.4 多条件筛选

组合条件:

sql
WHERE condition1 AND condition2
WHERE condition1 OR condition2

括号分组:

sql
WHERE (condition1 AND condition2) OR condition3

示例:

sql
-- AND示例
WHERE Product = 'Apples' AND Amount > 100

-- OR示例
WHERE Product = 'Apples' OR Product = 'Oranges'

-- 复杂分组
WHERE (Product = 'Apples' AND Amount > 100) OR Product = 'Oranges'

常见错误:

  • 使用= NULL而不是IS NULL
  • 复杂条件中忘记使用括号
  • 文本值周围忘记加引号
  • 忽略大小写敏感性

关键点:

  • 使用AND/OR组合条件
  • 括号控制求值顺序
  • 始终使用IS NULL检查NULL值
  • 为文本值加引号并考虑大小写敏感性

3. 🔄 数据转换

3.1 使用ORDER BY排序

基本语法:

sql
SELECT columns FROM table_name
ORDER BY column1 [ASC|DESC];

排序方向:

  • ASC - 升序(A-Z, 0-9) - 默认
  • DESC - 降序(Z-A, 9-0)

示例:

sql
-- 单列排序
SELECT * FROM sales
ORDER BY Amount DESC;

-- 多列排序
SELECT * FROM sales
ORDER BY Product ASC, Amount DESC;

关键点:

  • ORDER BY对最终结果集排序
  • 可以按多列顺序排序
  • 类似于Excel的排序功能

3.2 使用LIMIT分页结果

基本语法:

sql
SELECT columns FROM table_name
LIMIT number_of_rows;

常见用途:

  • 预览数据而不加载完整结果
  • 提高查询性能
  • 导出数据样本
  • 防止大型结果集过载

示例:

sql
-- 获取前100行
SELECT * FROM sales LIMIT 100;

-- 获取金额最高的10条记录
SELECT * FROM sales
ORDER BY Amount DESC
LIMIT 10;

关键点:

  • LIMIT控制返回的行数
  • 常与ORDER BY一起使用以获得有意义的结果
  • 许多工具出于安全考虑会应用默认LIMIT

3.3 列计算

基本语法:

sql
SELECT column1, column2, expression AS alias FROM table_name;

常见操作:

  • 算术运算: +, -, *, /
  • 函数: ROUND(), UPPER(), LOWER()
  • 连接: ||CONCAT()

示例:

sql
-- 简单计算
SELECT Product, Amount, Amount * 1.2 AS Amount_With_Tax FROM sales;

-- 使用函数
SELECT Product, UPPER(Product) AS Product_Upper FROM sales;

-- 数字四舍五入
SELECT Product, ROUND(Amount, 0) AS Rounded_Amount FROM sales;

关键点:

  • 计算在SELECT子句中完成
  • 使用AS命名计算列
  • 支持大多数类似Excel的操作和函数

3.4 文本处理

基本语法:

sql
SELECT text_function(column) FROM table_name;

常见文本函数:

  • 连接: ||CONCAT()
  • 子字符串: LEFT(), RIGHT(), SUBSTRING()
  • 大小写转换: UPPER(), LOWER()
  • 长度: LENGTH()LEN()

示例:

sql
-- 连接
SELECT Product || ' - $' || Amount AS Product_Price FROM sales;

-- 子字符串
SELECT LEFT(Product, 3) AS First3, SUBSTRING(Product, 2, 3) AS Mid3 FROM sales;

-- 大小写转换
SELECT UPPER(Product) AS UpperCase, LOWER(Product) AS LowerCase FROM sales;

-- 文本长度
SELECT Product, LENGTH(Product) AS Name_Length FROM sales;

关键点:

  • 功能类似于Excel文本函数
  • 语法可能因数据库系统略有不同
  • 对格式化和清理文本数据很有用

3.5 使用CASE进行智能分类

基本语法:

sql
SELECT column,
  CASE
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ELSE default_result
  END AS new_column
FROM table_name;

常见用途:

  • 从数值范围创建分类
  • 将值映射到标签
  • 使用默认值处理NULL值
  • 实现条件逻辑

示例:

sql
-- 简单分类
SELECT Product, Amount,
  CASE
    WHEN Amount >= 100 THEN '高'
    WHEN Amount >= 50 THEN '中'
    ELSE '低'
  END AS Amount_Category
FROM sales;

-- 值映射
SELECT Product,
  CASE
    WHEN Product = 'Apples' THEN '水果'
    WHEN Product = 'Carrots' THEN '蔬菜'
    ELSE '其他'
  END AS Product_Type
FROM sales;

-- NULL处理
SELECT Product,
  CASE
    WHEN Amount IS NULL THEN 0
    ELSE Amount
  END AS Amount_Filled
FROM sales;

关键点:

  • 类似于Excel的IF/IFS函数
  • 按顺序评估条件
  • 需要使用END关闭CASE语句
  • 使用AS命名结果列

4. 📊 数据聚合

4.1 基本聚合函数

基本语法:

sql
SELECT aggregate_function(column) FROM table_name;

常见函数:

函数功能示例
SUM()求和SUM(Amount)
AVG()计算平均值AVG(Amount)
COUNT()计数行数COUNT(*)
MIN()查找最小值MIN(Amount)
MAX()查找最大值MAX(Amount)

示例:

sql
-- 销售总额
SELECT SUM(Amount) AS Total_Sales FROM sales;

-- 多个聚合
SELECT
  COUNT(*) AS Row_Count,
  SUM(Amount) AS Total_Sales,
  AVG(Amount) AS Avg_Sale,
  MIN(Amount) AS Min_Sale,
  MAX(Amount) AS Max_Sale
FROM sales;

关键点:

  • 类似于Excel的汇总函数和数据透视表值
  • 可以在同一查询中使用多个函数
  • 计算时忽略NULL值

4.2 GROUP BY: 改变游戏规则

基本语法:

sql
SELECT column, aggregate_function(column)
FROM table_name
GROUP BY column;

示例:

sql
-- 按产品统计销售总额
SELECT Product, SUM(Amount) AS Total_Sales
FROM sales
GROUP BY Product;

-- 按日期统计销售总额
SELECT SaleDate, SUM(Amount) AS Total_Sales
FROM sales
GROUP BY SaleDate
ORDER BY SaleDate;

关键规则:

  • SELECT中每个非聚合列必须在GROUP BY中
  • 类似于Excel数据透视表的行标签
  • 可以按多列分组(逗号分隔)

关键点:

  • GROUP BY允许按类别汇总数据
  • 对创建有意义的报告至关重要
  • 常与ORDER BY一起使用以获得排序结果

4.3 多级分组

基本语法:

sql
SELECT column1, column2, aggregate_function(column)
FROM table_name
GROUP BY column1, column2;

示例:

sql
-- 按产品和日期统计销售总额
SELECT Product, SaleDate, SUM(Amount) AS Total_Sales
FROM sales
GROUP BY Product, SaleDate
ORDER BY Product, SaleDate;

关键点:

  • 类似于Excel数据透视表中的嵌套行标签
  • GROUP BY中列的顺序影响分组
  • 每个分组列组合获得自己的行

4.4 使用HAVING筛选分组

基本语法:

sql
SELECT column, aggregate_function(column)
FROM table_name
GROUP BY column
HAVING condition;

示例:

sql
-- 总销售额超过200的产品
SELECT Product, SUM(Amount) AS Total_Sales
FROM sales
GROUP BY Product
HAVING SUM(Amount) > 200;

-- 组合WHERE和HAVING
SELECT Product, SUM(Amount) AS Total_Sales
FROM sales
WHERE SaleDate BETWEEN '2024-05-01' AND '2024-05-31'
GROUP BY Product
HAVING Total_Sales > 200;

关键点:

  • HAVING在聚合后筛选分组(WHERE在聚合前筛选行)
  • 可以引用聚合函数或列别名
  • 类似于在Excel中筛选数据透视表结果

5. 📅 高级技巧

5.1 日期处理

基本日期筛选:

sql
SELECT * FROM sales
WHERE SaleDate BETWEEN '2024-05-01' AND '2024-05-31';

日期提取函数:

sql
SELECT
  SaleDate,
  YEAR(SaleDate) AS Sale_Year,
  MONTH(SaleDate) AS Sale_Month,
  DAY(SaleDate) AS Sale_Day
FROM sales;

按日期部分分组:

sql
SELECT
  YEAR(SaleDate) AS Year,
  MONTH(SaleDate) AS Month,
  SUM(Amount) AS Total_Sales
FROM sales
GROUP BY YEAR(SaleDate), MONTH(SaleDate)
ORDER BY Year, Month;

日期运算:

sql
-- 添加天数
SELECT SaleDate, SaleDate + 7 AS Week_Later FROM sales;

-- 日期差异(天数)
SELECT EndDate - StartDate AS Days_Diff FROM sales;

常见数据库差异:

函数PostgreSQL/OracleSQL ServerMySQLSnowflake
提取年份YEAR(date)YEAR(date)YEAR(date)YEAR(date)
格式化日期TO_CHAR(date, 'YYYY-MM')FORMAT(date, 'yyyy-MM')DATE_FORMAT(date, '%Y-%m')TO_VARCHAR(date, 'YYYY-MM')
添加天数date + nDATEADD(day, n, date)DATE_ADD(date, INTERVAL n DAY)DATEADD(day, n, date)

关键点:

  • 日期函数因数据库而异 - 请查阅文档
  • 功能类似于Excel日期函数
  • 对基于时间的分析和报告至关重要

5.2 NULL值解决方案

理解NULL:

  • 表示缺失/未知数据(类似于Excel空白)
  • 不等于零或空字符串

筛选NULL值:

sql
-- 查找NULL值
SELECT * FROM sales WHERE Amount IS NULL;

-- 排除NULL值
SELECT * FROM sales WHERE Amount IS NOT NULL;

替换NULL值:

sql
-- COALESCE提供默认值
SELECT Product, COALESCE(Amount, 0) AS Amount_Filled FROM sales;

-- CASE语句替代方案
SELECT Product,
  CASE
    WHEN Amount IS NULL THEN '缺失'
    ELSE CAST(Amount AS VARCHAR)
  END AS Amount_Status
FROM sales;

关键点:

  • 始终使用IS NULL/IS NOT NULL检查NULL值
  • COALESCE是处理NULL值的标准方法
  • CASE提供更灵活的NULL处理

5.3 子查询基础

什么是子查询?

  • 嵌套在其他查询中的查询
  • 类似于Excel中的辅助表/公式
  • 可用于WHERE、IN、EXISTS、SELECT子句

基本子查询语法:

sql
-- 使用子查询结果筛选
SELECT * FROM sales
WHERE Amount > (SELECT AVG(Amount) FROM sales);

-- 使用子查询的IN
SELECT * FROM sales
WHERE Product IN (SELECT Product FROM featured_products);

-- 使用子查询的NOT IN
SELECT * FROM sales
WHERE Product NOT IN (SELECT Product FROM discontinued_products);

NOT IN的NULL处理:

sql
-- 安全的NOT IN(过滤NULL)
SELECT * FROM sales
WHERE Product NOT IN (
  SELECT Product FROM discontinued_products
  WHERE Product IS NOT NULL
);

-- 使用COALESCE的替代方案
SELECT * FROM sales
WHERE Product NOT IN (
  SELECT COALESCE(Product, '???') FROM discontinued_products
);

关键点:

  • 子查询支持动态筛选
  • 带有NULL的NOT IN可能导致意外结果
  • 在使用NOT IN的子查询中始终处理NULL值

6. 🤝 表连接

6.1 INNER JOIN基础

Excel类比: 类似于工作表之间的VLOOKUP

基本语法:

sql
SELECT t1.column1, t2.column2
FROM table1 t1
INNER JOIN table2 t2
  ON t1.common_column = t2.common_column;

示例:

sql
-- 合并销售和产品详情
SELECT s.ProductID, p.ProductName, s.Amount
FROM sales s
INNER JOIN products p
  ON s.ProductID = p.ProductID;

表别名最佳实践:

  • 使用简短、有意义的别名(如s表示sales,p表示products)
  • 在整个查询中保持别名一致
  • 帮助区分同名列

关键点:

  • INNER JOIN只返回两个表中匹配的行
  • 连接条件(ON子句)是必需的
  • 可以连接任何匹配列,不限于ID

6.2 LEFT JOIN实践

Excel类比: 类似保留#N/A错误的VLOOKUP

基本语法:

sql
SELECT t1.column1, t2.column2
FROM table1 t1
LEFT JOIN table2 t2
  ON t1.common_column = t2.common_column;

示例: 包含所有销售,即使没有产品信息

sql
SELECT s.ProductID, p.ProductName, s.Amount
FROM sales s
LEFT JOIN products p
  ON s.ProductID = p.ProductID;

查找不匹配项:

sql
-- 没有销售的产品
SELECT p.ProductID, p.ProductName
FROM products p
LEFT JOIN sales s ON p.ProductID = s.ProductID
WHERE s.ProductID IS NULL;

-- 没有产品信息的销售
SELECT s.ProductID, s.Amount
FROM sales s
LEFT JOIN products p ON s.ProductID = p.ProductID
WHERE p.ProductID IS NULL;

关键点:

  • LEFT JOIN保留左表所有行
  • 不匹配项显示为NULL值
  • 使用WHERE IS NULL查找不匹配行

6.3 多表连接

Excel类比: 类似跨工作表的多个VLOOKUP链

基本语法:

sql
SELECT t1.col, t2.col, t3.col
FROM table1 t1
JOIN table2 t2 ON t1.key = t2.key
JOIN table3 t3 ON t1.key = t3.key;

示例: 连接销售、产品和客户表

sql
SELECT s.SaleID, s.Amount, p.ProductName, c.CustomerName
FROM sales s
INNER JOIN products p ON s.ProductID = p.ProductID
INNER JOIN customers c ON s.CustomerID = c.CustomerID;

最佳实践:

  • 使用清晰、一致的表别名(s,p,c)
  • 按逻辑顺序连接表(从主表开始)
  • 增量测试连接(一次添加一个连接)

关键点:

  • 可以根据需要连接任意多表
  • 每个连接都需要ON条件
  • 别名对可读性至关重要

6.4 处理连接重复项

常见原因:

  • 连接列中存在重复值
  • 多对多关系
  • 数据质量问题

诊断重复项:

sql
-- 检查重复键
SELECT join_column, COUNT(*)
FROM table
GROUP BY join_column
HAVING COUNT(*) > 1;

问题示例:

sql
-- 如果products有重复项可能产生重复行
SELECT s.SaleID, p.ProductName, s.Amount
FROM sales s
JOIN products p ON s.ProductID = p.ProductID;

解决方案:

  1. 从源头修复数据质量(删除重复项)
  2. 使用DISTINCT(临时解决方案):
sql
SELECT DISTINCT s.SaleID, p.ProductName, s.Amount
FROM sales s
JOIN products p ON s.ProductID = p.ProductID;
  1. 确保连接列是唯一键

关键点:

  • 存在重复项时连接会成倍增加行数
  • 连接前始终检查重复项
  • 优先修复数据而非使用DISTINCT

6.5 将多表Excel迁移到SQL

Excel到SQL等效操作:

Excel操作SQL等效操作
跨表VLOOKUPJOIN
合并多表多个JOIN
删除重复项SELECT DISTINCT
连接后筛选WHEREJOIN

迁移示例:

sql
-- Excel: 使用VLOOKUP合并销售、产品、客户表
-- SQL等效:
SELECT s.SaleID, s.Amount, p.ProductName, c.CustomerName
FROM sales s
JOIN products p ON s.ProductID = p.ProductID
JOIN customers c ON s.CustomerID = c.CustomerID;

迁移优势:

  • 更可靠地处理复杂关系
  • 自动化重复的多表分析
  • 为团队提供单一数据源

关键点:

  • SQL连接取代易错的VLOOKUP
  • 从复制常见的多表报表开始
  • 记录查询以便团队协作