SQL 的汇总分析
SQL 的汇总分析功能强大,主要用于对数据进行统计、分组、聚合和筛选。汇总分析在报表、数据挖掘、商业智能中非常重要,尤其是在处理海量数据时,可以帮助我们快速得出关键指标和趋势。以下是 SQL 汇总分析的详细讲解,结合最新 SQL 功能与实践。
1. 聚合函数
SQL 提供了多种聚合函数,用于汇总分析。
常用聚合函数
| 函数 | 作用 |
|---|---|
SUM() | 计算某列数值的总和 |
AVG() | 计算某列数值的平均值 |
COUNT() | 统计行数或某列非 NULL 值的数量 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
GROUP_CONCAT() | 将分组后的值拼接成字符串(MySQL) |
示例:聚合计算
假设我们有一张 sales 表:
id | product | category | quantity | price
-------------------------------------------------
1 | Laptop | Electronics| 2 | 1000
2 | Smartphone| Electronics| 3 | 500
3 | Chair | Furniture | 5 | 200
4 | Table | Furniture | 2 | 800
5 | Laptop | Electronics| 1 | 1000
计算总销售额
SELECT SUM(quantity * price) AS total_sales FROM sales;
结果:
total_sales
-----------
5900
计算每个类别的平均价格
SELECT
category,
AVG(price) AS avg_price
FROM
sales
GROUP BY
category;
结果:
category | avg_price
-------------------------
Electronics | 833.33
Furniture | 500
统计每个产品的销售总量
SELECT
product,
SUM(quantity) AS total_quantity
FROM
sales
GROUP BY
product;
结果:
product | total_quantity
------------------------------
Laptop | 3
Smartphone | 3
Chair | 5
Table | 2
2. 分组分析(GROUP BY)
GROUP BY 是汇总分析的核心,用于将数据按某列(或多列)分组,然后进行聚合。
多字段分组
分组可以基于多个字段,以实现更细粒度的统计。
示例:按类别和产品分组,统计销售数量
SELECT
category,
product,
SUM(quantity) AS total_quantity
FROM
sales
GROUP BY
category, product;
结果:
category | product | total_quantity
----------------------------------------------
Electronics | Laptop | 3
Electronics | Smartphone | 3
Furniture | Chair | 5
Furniture | Table | 2
3. 条件聚合(HAVING)
HAVING 用于对分组后的结果进行过滤。与 WHERE 不同,HAVING 是在分组和聚合之后起作用的。
示例:筛选总销售额大于 $1000 的类别
SELECT
category,
SUM(quantity * price) AS total_sales
FROM
sales
GROUP BY
category
HAVING
total_sales > 1000;
结果:
category | total_sales
---------------------------
Electronics | 4000
Furniture | 1900
4. 窗口函数
窗口函数(Window Functions)在 SQL 的汇总分析中非常强大,它允许在不改变行数的情况下进行统计和排名。
常用窗口函数
| 函数 | 作用 |
|---|---|
ROW_NUMBER() | 按指定排序分配连续行号 |
RANK() | 按指定排序分配排名,相同排名跳过名次 |
DENSE_RANK() | 类似 RANK(),但不会跳过名次 |
SUM() | 在窗口范围内计算总和 |
AVG() | 在窗口范围内计算平均值 |
COUNT() | 在窗口范围内统计行数 |
示例:按类别对产品进行销量排名
SELECT
category,
product,
SUM(quantity) AS total_quantity,
RANK() OVER (PARTITION BY category ORDER BY SUM(quantity) DESC) AS rank
FROM
sales
GROUP BY
category, product;
结果:
category | product | total_quantity | rank
-----------------------------------------------------
Electronics | Laptop | 3 | 1
Electronics | Smartphone | 3 | 1
Furniture | Chair | 5 | 1
Furniture | Table | 2 | 2
5. 子查询与嵌套分析
子查询可用于更复杂的汇总需求。
示例:查询销量最高的产品类别
SELECT
category
FROM
(SELECT
category,
SUM(quantity) AS total_quantity
FROM
sales
GROUP BY
category) AS subquery
WHERE
total_quantity = (SELECT MAX(total_quantity)
FROM
(SELECT SUM(quantity) AS total_quantity
FROM sales
GROUP BY category) AS max_query);
结果:
category
---------
Furniture
6. CTE(公共表表达式)
CTE 是提高查询可读性的重要工具,适合分步处理复杂的汇总分析。
示例:分步计算每个类别的总销售额,再筛选出销量最高的类别
WITH CategorySales AS (
SELECT
category,
SUM(quantity * price) AS total_sales
FROM
sales
GROUP BY
category
)
SELECT
category
FROM
CategorySales
WHERE
total_sales = (SELECT MAX(total_sales) FROM CategorySales);
7. JSON 汇总分析
MySQL 8.0+ 和 PostgreSQL 提供了对 JSON 数据的支持,适用于非结构化数据的汇总。
示例:以 JSON 格式返回每个类别的产品和总销量
SELECT
category,
JSON_ARRAYAGG(
JSON_OBJECT('product', product, 'total_quantity', SUM(quantity))
) AS product_summary
FROM
sales
GROUP BY
category;
结果:
category | product_summary
----------------------------------------
Electronics | [{"product": "Laptop", "total_quantity": 3},
{"product": "Smartphone", "total_quantity": 3}]
Furniture | [{"product": "Chair", "total_quantity": 5},
{"product": "Table", "total_quantity": 2}]
8. 优化汇总分析的性能
- 使用索引:
为常用的分组字段(如category)创建索引,加速查询。
CREATE INDEX idx_category ON sales(category);
- 避免冗余计算:
使用 CTE 或子查询减少重复的聚合操作。 - 分布式查询:
在大规模数据处理场景中,使用支持分布式计算的数据库(如 Google BigQuery、Apache Hive)。
以上是 SQL 汇总分析的详细讲解,包括常用方法与最新技术的结合。更多详细内容请关注其他相关文章。