当我们处理数据库中的数据时,经常需要对大量细节数据进行汇总分析。比如电商平台需要了解每个商品类别的总销量,或者教育机构想知道每个课程的平均评分。这时候,我们就需要用到SQL中的分组和聚合功能。
其实我们在前面的课程中已经多次使用过分组和聚合功能,比如我们使用 GROUP BY 子句来对数据进行分组,使用聚合函数来对数据进行统计计算。
数据分组就像把杂乱无章的数据按照某种规律整理成不同的堆叠,然后对每一堆数据进行统计计算。这个过程能帮助我们从大量原始数据中提取出有价值的商业洞察。

假设我们有一个在线学习平台的课程表,记录了每门课程的创建者信息。如果平台管理员想了解每位老师创建了多少门课程,直接查看原始数据会非常低效。
|SELECT teacher_id FROM courses;
这样的查询会返回所有课程记录,如果有数千门课程,我们很难快速统计每位老师的课程数量。这时候就需要使用分组功能。
通过添加 GROUP BY 子句,我们可以让数据库帮我们自动整理数据:
|SELECT teacher_id FROM courses GROUP BY teacher_id;
这个查询会返回每个不重复的教师ID,相当于自动去重并分组。但仅仅分组还不够,我们通常需要知道每个分组里有多少条记录,这个时候就需要使用聚合函数。
聚合函数(Aggregate Functions)是数据库中用于对一组数据进行统计和汇总计算的专用函数。它们通常与 GROUP BY 子句结合使用,对分组后的每一组数据执行如计数、求和、平均值、最大值、最小值等数学运算。
通过聚合函数,我们可以高效地从大量原始数据中提取出有意义的统计指标,支持业务分析和决策,例如下面是一个简单的COUNT的示例:
|SELECT teacher_id, COUNT(*) as course_count FROM courses GROUP BY teacher_id;
通过以上的查询,我们就可以知道每位老师有多少门课程。
聚合函数必须与GROUP BY子句配合使用,否则会对整个表的数据进行计算
COUNT() 是最常用的聚合函数之一。它的作用是统计每个分组中包含的记录条数。比如,如果我们按照 teacher_id 对课程表分组,COUNT() 就会返回每位老师各自创建了多少门课程。 COUNT() 可以统计所有行(COUNT()),也可以只统计某一列中非空的行(如 COUNT(rating) 只统计有评分的课程数量)。这种统计方式非常适合用来快速了解每个分组下数据的分布和数量。
|-- 统计每位老师创建的课程数量 SELECT teacher_id, COUNT(*) as total_courses FROM courses GROUP BY teacher_id;
SUM() 用于对某个数值型字段进行求和运算。它会将每个分组(或整个表)中指定字段的所有数值相加,得到总和。 比如,我们可以用 SUM() 统计每位老师所有课程的总学时(如 duration_hours 字段),也可以用来计算总销售额(如 sales 字段)。 举例来说,如果一位老师有三门课程,学时分别为 10、20、30,则 SUM(duration_hours) 的结果就是 60。SUM() 常用于财务统计、工作量统计等需要累计数值的场景。
|-- 计算每位老师所有课程的总时长 SELECT teacher_id, SUM(duration_hours) as total_hours FROM courses GROUP BY teacher_id;
AVG() 函数用于计算某个数值字段的平均值。它会将每个分组(或整个表)中该字段的所有数值相加,然后除以记录的数量,得出平均数。 比如,我们可以用 AVG(rating) 计算每位老师课程的平均评分,也可以用 AVG(price) 计算每个类别下课程的平均价格。 平均值常用于分析整体水平、评估绩效或发现异常数据。例如,如果某位老师的平均评分明显高于其他老师,就可能说明其课程质量较高。
|-- 计算每位老师课程的平均评分 SELECT teacher_id, AVG(rating) as avg_rating FROM courses GROUP BY teacher_id;
MAX() 和 MIN() 函数分别用于找出每个分组中某个字段的最大值和最小值。比如,如果我们按照 teacher_id 对课程表分组,MAX(price) 就会返回每位老师所开设课程中的最高价格,MIN(price) 则返回最低价格。 这样可以帮助我们了解每位老师课程的价格区间,或者在其他场景下找出每组数据中的极值(如最高分、最低分、最大销量等)。在实际查询中,通常会和 GROUP BY 子句一起使用,实现对每个分组的最大/最小值统计。
|-- 找出每位老师课程的最高和最低价格 SELECT teacher_id, MAX(price) as highest_price, MIN(price) as lowest_price FROM courses GROUP BY teacher_id;
在实际的数据分析中,我们经常需要同时获取多个统计指标,比如每个分组下的数量、平均值、总和、最大值、最小值等。此时,可以在同一个查询语句中同时使用多个不同的聚合函数。这样不仅能一次性得到更丰富的分析结果,还能减少多次查询带来的性能开销。 例如,下面的查询会同时统计每个课程类别下的课程数量、平均价格、总报名人数和最高评分等信息,帮助我们从多个维度全面了解数据的分布和特征:
|SELECT category, COUNT(*) as course_count, AVG(price) as avg_price, SUM(enrollment) as total_students, MAX(rating) as best_rating FROM courses GROUP BY category;
当我们在SELECT子句中只使用聚合函数(比如COUNT、SUM、AVG等),而没有包含任何普通字段时,数据库会把整张表当作一个整体来进行统计,这种情况就叫做“隐式分组”。 此时,查询的结果只会返回一行,表示对全表数据的汇总结果。例如,如果我们想统计所有课程的总数、平均价格和总报名人数,就可以只写聚合函数,不需要加GROUP BY,数据库会自动把所有数据当成一个分组来处理。
|-- 隐式分组:计算所有课程的统计信息 SELECT COUNT(*) as total_courses, AVG(price) as avg_price, SUM(enrollment) as total_enrollment FROM courses;
但如果我们既想要聚合函数的结果,又想要普通字段,就必须使用显式的 GROUP BY 子句:
|-- 显式分组:按类别分组计算统计信息 SELECT category, COUNT(*) as course_count, AVG(price) as avg_price FROM courses GROUP BY category;
如果SELECT子句中包含非聚合函数的字段,这些字段必须出现在GROUP BY子句中,否则查询会报错
在实际的数据分析中,除了统计总数之外,我们经常还需要统计某个字段中不重复(唯一)的值的数量。这在分析去重后的数据分布时非常有用。 例如,在一个课程表中,假设我们想知道每个课程类别下有多少位不同的老师在授课,而不是所有课程的总数。也就是说,我们希望统计每个类别中“唯一教师ID”的数量,这样可以了解每个类别的师资覆盖面有多广。
|-- 统计每个类别中不同老师的数量 SELECT category, COUNT(DISTINCT teacher_id) as unique_teachers FROM courses GROUP BY category;
这里的 DISTINCT 关键字确保我们只统计不重复的教师ID,即使同一位老师在同一类别下有多门课程,也只会被计算一次。
聚合函数不仅可以直接用于某个字段本身,还可以用于更复杂的计算表达式。也就是说,我们可以在聚合函数内部对字段进行运算、组合或处理,然后再对结果进行统计。例如,可以对两个字段相除、相加,或者用条件表达式生成新的值,再用聚合函数(如AVG、SUM等)对这些计算结果进行汇总。
假设我们想要统计每位老师的“平均学时密度”,可以用 AVG(duration_hours / duration_days),即先计算每门课程的学时密度(学时/天),再对每位老师所有课程的密度取平均值:
|-- 计算每位老师课程的平均学时密度(学时/天) SELECT teacher_id, AVG(duration_hours / duration_days) as avg_intensity FROM courses GROUP BY teacher_id;
在进行聚合计算时,NULL值的处理方式与普通数值不同。大多数聚合函数(如SUM、AVG、COUNT(列名)等)在计算时会自动忽略值为NULL的记录,只对非NULL的值进行统计。例如,SUM只会累加非NULL的数值,AVG只会计算非NULL值的平均数。如果某一行的字段为NULL,这一行在聚合时会被跳过,不参与计算。
需要特别注意的是,COUNT()与COUNT(列名)的行为不同:COUNT()会统计所有行的数量,包括NULL值;而COUNT(列名)只统计该列非NULL的行数。
下面我们通过一个具体的实验来演示NULL值在聚合函数中的处理方式:
|-- 创建测试数据 CREATE TABLE test_scores ( student_id INT, score INT ); INSERT INTO test_scores VALUES (1, 85), (2, 92), (3, 78), (4, NULL);
现在对这些数据进行聚合:
|SELECT COUNT(*) as total_rows, COUNT(score) as non_null_scores, AVG(score) as avg_score, SUM(score) as total_score FROM test_scores;
结果会显示:
|+------------+-----------------+-----------+-------------+ | total_rows | non_null_scores | avg_score | total_score | +------------+-----------------+-----------+-------------+ | 4 | 3 | 85.0000 | 255 | +------------+-----------------+-----------+-------------+
除了COUNT(*)会统计所有行之外,其他聚合函数都会自动忽略NULL值进行计算
在实际的业务分析中,往往需要同时考虑多个维度对数据进行分组统计,这样可以获得更细致、更有针对性的分析结果。例如,在一个课程平台中,我们不仅关心每个课程类别(如编程、设计、语言等)的整体情况,还可能希望进一步细分,了解在不同难度级别(如初级、中级、高级)下,各类别的课程分布和表现。 这种“多维分组”可以帮助我们发现不同类别和难度组合下的数据特征,比如哪些类别的高级课程数量较多,或者某一类别在初级难度下最受欢迎。实现这种多维度的交叉分析,只需要在SQL的GROUP BY子句中同时列出多个字段即可,数据库会自动按照每种字段组合进行分组统计。
|SELECT category, difficulty_level, COUNT(*) as course_count, AVG(price) as avg_price FROM courses GROUP BY category, difficulty_level;
除了直接使用表中的原始字段进行分组,我们还可以利用计算表达式对数据进行分组。所谓“基于表达式的分组”,就是在GROUP BY子句中使用某些函数或运算,对字段进行加工处理后再分组。这样可以实现更灵活的数据聚合需求。
举个例子,假设我们的课程表中有一个 created_date 字段,记录了每门课程的创建日期。如果我们想要统计每一年创建的课程数量,就可以通过对 created_date 字段使用 YEAR() 函数,将日期转换成年份,然后按年份分组。这样,数据库会自动把同一年份的数据归为一组,方便我们进行年度统计分析。
这种基于表达式的分组方式,特别适合需要按照时间(如年、月、季度)、区间、类别映射等自定义规则进行分组的场景。
|SELECT YEAR(created_date) as creation_year, COUNT(*) as courses_created FROM courses GROUP BY YEAR(created_date) ORDER BY creation_year;
在实际的数据分析中,我们经常不仅仅关心每个分组的详细统计结果,还希望能够看到各个分组的汇总(比如每个类别的小计,甚至所有数据的总计)。如果手动分别查询每一级的汇总会非常繁琐。为此,MySQL 提供了 WITH ROLLUP 选项,可以在分组统计的基础上,自动为我们生成各级别的汇总行。
具体来说,WITH ROLLUP 会在原有的分组结果下方,依次增加每个分组字段的“小计”以及所有数据的“总计”行。例如,如果我们按照“课程类别”和“难度等级”两个字段分组,使用 WITH ROLLUP 后,查询结果会自动包含:
这样,我们可以以一条 SQL 语句同时获得详细分组和各级汇总。
|SELECT category, difficulty_level, COUNT(*) as course_count FROM courses GROUP BY category, difficulty_level WITH ROLLUP;
在SQL查询中,若需对分组(GROUP BY)后的聚合结果进行筛选,必须使用HAVING子句,而不能用WHERE子句。原因在于,WHERE子句是在分组和聚合计算之前对原始数据进行行级过滤,而HAVING子句则是在分组和聚合之后,对每个分组的统计结果进行条件判断和过滤。(回想我们之前学过的SQL执行顺序)
因此,凡是涉及聚合函数(如COUNT、SUM、AVG等)的筛选条件,都应放在HAVING子句中实现。
|SELECT category, COUNT(*) as course_count, AVG(price) as avg_price FROM courses WHERE status = 'active' -- 分组前过滤:只统计活跃课程 GROUP BY category HAVING COUNT(*) >= 5; -- 分组后过滤:只显示课程数≥5的类别
聚合函数只能在SELECT子句和HAVING子句中使用,不能在WHERE子句中使用
让我们通过一个完整的电商平台案例来综合运用这些知识。我们将创建一个完整的销售数据分析系统,从建表到数据插入,再到各种分析查询。
首先,我们需要创建电商平台的核心数据表。为了进行完整的销售分析,我们需要创建以下几个表:
|-- 创建电商平台的核心数据表 -- 1. 商品表:存储所有商品的基本信息 CREATE TABLE products ( product_id INT PRIMARY KEY AUTO_INCREMENT, -- 商品ID,主键自增 product_name VARCHAR(200) NOT NULL, -- 商品名称 category VARCHAR(50) NOT NULL, -- 商品类别(如:电子产品、服装、家居等)
现在让我们通过一些练习题来巩固SQL分组与聚合的知识。我们将继续使用上面的电商平台数据库来进行练习。
统计每个商品类别的基本信息:查询每个商品类别下的商品总数、平均价格和最高价格
|SELECT category, COUNT(*) as product_count, ROUND(AVG(price), 2) as avg_price, MAX(price) as max_price FROM products WHERE status = 'active' GROUP BY category HAVING COUNT(*) >= 3 ORDER BY product_count DESC;
分析卖家销售业绩:查询每个卖家的总销售额、销售数量和平均订单金额
|SELECT s.seller_name, s.seller_type, YEAR(s.registration_date) as registration_year, SUM(so.total_amount) as total_sales, SUM(so.quantity) as total_quantity, ROUND(AVG(so.total_amount),
分析2023年每月销售趋势:统计每月的订单数量、销售额和平均订单金额
|SELECT DATE_FORMAT(order_date, '%Y-%m') as month, COUNT(*) as order_count, SUM(total_amount) as monthly_sales, ROUND(AVG(total_amount), 2) as avg_order_amount, ROUND( (SUM(total_amount) - LAG(SUM(total_amount)) OVER (ORDER BY DATE_FORMAT
分析商品评价对销售的影响:统计每个商品的平均评分、评价数量和总销售额
|SELECT p.product_name, ROUND(AVG(pr.rating), 1) as avg_rating, COUNT(pr.review_id) as review_count, SUM(so.total_amount) as total_sales, ROUND(SUM(so.total_amount) /
下表详细介绍了各个表的结构和用途:
说明:
products 表为商品的主表,包含商品的所有基本属性,并对常用查询字段(如 category、status、price)建立了索引以提升查询效率。sellers 表记录卖家信息,可用于分析卖家类型、注册时间、平均评分等。sales_orders 表详细记录每一笔销售订单,包括商品、卖家、顾客、订单状态、地区等,是销售数据分析的核心表。product_reviews 表存储用户对商品的评价及评分,可用于分析商品口碑和用户满意度。每个表的字段和索引设计都考虑了实际业务分析和查询性能需求。
现在我们需要为这些表插入一些真实的测试数据,以便进行后续的分析:
|-- 插入卖家数据 INSERT INTO sellers (seller_name, seller_type, registration_date) VALUES ('华为官方旗舰店', '企业', '2020-01-15'), ('小米之家', '企业', '2020-03-20'), ('苹果专卖店', '企业', '2019-12-01'), ('联想电脑专营店', '企业', '2020-05-10'), ('美特斯邦威', '企业', '2018-08-15'), ('李宁官方店', '企业', '2019-06-01'), ('海尔电器', '企业', '2017-11-20'), ('苏宁易购', '企业', '2016-09-15'), ('张三数码', '个人', '2021-01-10'), ('王五精品店', '个人', '2021-03-05'); -- 插入商品数据 INSERT INTO products (product_name, category, subcategory, brand, price, cost_price, stock_quantity, status, rating, review_count, created_date, seller_id) VALUES -- 电子产品 ('华为Mate 50', '电子产品', '手机', '华为', 5999.00, 4500.00, 100, 'active', 4.8, 1250, '2023-09-15', 1), ('华为P60', '电子产品', '手机', '华为', 6999.00, 5200.00, 80, 'active', 4.9, 980, '2023-10-20', 1), ('小米14', '电子产品', '手机', '小米', 3999.00, 3200.00, 150, 'active', 4.6, 2100, '2023-10-01', 2), ('小米13 Pro', '电子产品', '手机', '小米', 4999.00, 3800.00, 120, 'active', 4.7, 1800, '2023-08-15', 2), ('iPhone 15', '电子产品', '手机', '苹果', 7999.00, 6500.00, 200, 'active', 4.8, 3200, '2023-09-22', 3), ('iPhone 15 Pro', '电子产品', '手机', '苹果', 9999.00, 8000.00, 150, 'active', 4.9, 2800, '2023-09-22', 3), ('联想小新Pro', '电子产品', '笔记本电脑', '联想', 5999.00, 4800.00, 80, 'active', 4.5, 950, '2023-07-10', 4), ('华为MateBook X', '电子产品', '笔记本电脑', '华为', 8999.00, 7200.00, 60, 'active', 4.7, 1200, '2023-08-05', 1), ('MacBook Air M2', '电子产品', '笔记本电脑', '苹果', 9999.00, 8500.00, 90, 'active', 4.8, 1600, '2023-06-15', 3), -- 服装 ('美特斯邦威男士卫衣', '服装', '上衣', '美特斯邦威', 199.00, 120.00, 300, 'active', 4.3, 450, '2023-11-01', 5), ('李宁跑步鞋', '服装', '鞋子', '李宁', 399.00, 250.00, 200, 'active', 4.6, 780, '2023-10-15', 6), ('李宁篮球鞋', '服装', '鞋子', '李宁', 499.00, 320.00, 150, 'active', 4.7, 650, '2023-09-20', 6), ('美特斯邦威牛仔裤', '服装', '裤子', '美特斯邦威', 299.00, 180.00, 250, 'active', 4.2, 380, '2023-08-10', 5), -- 家居电器 ('海尔冰箱', '家居电器', '大家电', '海尔', 3999.00, 3000.00, 50, 'active', 4.5, 320, '2023-05-20', 7), ('海尔洗衣机', '家居电器', '大家电', '海尔', 2999.00, 2200.00, 40, 'active', 4.4, 280, '2023-06-10', 7), ('美的空调', '家居电器', '大家电', '美的', 3499.00, 2800.00, 35, 'active', 4.3, 240, '2023-07-05', 8), ('苏宁智能电视', '家居电器', '大家电', '苏宁', 1999.00, 1600.00, 60, 'active', 4.1, 180, '2023-08-20', 8); -- 插入销售订单数据(2023年全年) INSERT INTO sales_orders (product_id, seller_id, order_date, quantity, unit_price, total_amount, discount_amount, payment_method, order_status, region) VALUES -- 1月份销售数据 (1, 1, '2023-01-15', 2, 5999.00, 11998.00, 0, '支付宝', 'delivered', '北京'), (1, 1, '2023-01-18', 1, 5999.00, 5999.00, 0, '微信支付', 'delivered', '上海'), (2, 1, '2023-01-20', 1, 6999.00, 6999.00, 0, '支付宝', 'delivered', '深圳'), (3, 2, '2023-01-25', 3, 3999.00, 11997.00, 200, '支付宝', 'delivered', '广州'), (4, 2, '2023-01-28', 2, 4999.00, 9998.00, 0, '微信支付', 'delivered', '北京'), -- 2月份销售数据 (5, 3, '2023-02-05', 1, 7999.00, 7999.00, 0, '支付宝', 'delivered', '上海'), (6, 3, '2023-02-08', 1, 9999.00, 9999.00, 500, '微信支付', 'delivered', '深圳'), (7, 4, '2023-02-12', 1, 5999.00, 5999.00, 0, '支付宝', 'delivered', '北京'), (8, 1, '2023-02-15', 1, 8999.00, 8999.00, 300, '支付宝', 'delivered', '广州'), (9, 3, '2023-02-18', 2, 9999.00, 19998.00, 1000, '微信支付', 'delivered', '上海'), -- 3月份销售数据(春节促销期) (1, 1, '2023-03-01', 5, 5599.00, 27995.00, 2000, '支付宝', 'delivered', '全国'), (2, 1, '2023-03-02', 3, 6599.00, 19797.00, 1200, '微信支付', 'delivered', '全国'), (3, 2, '2023-03-05', 8, 3599.00, 28792.00, 2400, '支付宝', 'delivered', '全国'), (4, 2, '2023-03-08', 4, 4599.00, 18396.00, 1600, '微信支付', 'delivered', '全国'), (5, 3, '2023-03-10', 6, 7599.00, 45594.00, 3600, '支付宝', 'delivered', '全国'), (6, 3, '2023-03-12', 2, 9499.00, 18998.00, 2000, '微信支付', 'delivered', '全国'), -- 继续插入更多月份的数据... (10, 5, '2023-04-15', 10, 199.00, 1990.00, 100, '支付宝', 'delivered', '北京'), (11, 6, '2023-04-18', 8, 399.00, 3192.00, 200, '微信支付', 'delivered', '上海'), (12, 6, '2023-04-20', 6, 499.00, 2994.00, 300, '支付宝', 'delivered', '广州'), (13, 5, '2023-04-25', 12, 299.00, 3588.00, 300, '支付宝', 'delivered', '深圳'), (14, 7, '2023-05-02', 2, 3999.00, 7998.00, 400, '微信支付', 'delivered', '北京'), (15, 7, '2023-05-05', 1, 2999.00, 2999.00, 0, '支付宝', 'delivered', '上海'), (16, 8, '2023-05-08', 3, 3499.00, 10497.00, 500, '微信支付', 'delivered', '广州'), (17, 8, '2023-05-10', 4, 1999.00, 7996.00, 400, '支付宝', 'delivered', '深圳'), -- 6月份夏季促销 (10, 5, '2023-06-15', 25, 179.00, 4475.00, 500, '支付宝', 'delivered', '全国'), (11, 6, '2023-06-18', 20, 359.00, 7180.00, 800, '微信支付', 'delivered', '全国'), (12, 6, '2023-06-20', 15, 449.00, 6735.00, 750, '支付宝', 'delivered', '全国'), (13, 5, '2023-06-25', 30, 269.00, 8070.00, 900, '微信支付', 'delivered', '全国'), -- 7-12月份的销售数据(继续添加更多数据以丰富分析) (1, 1, '2023-07-15', 12, 5799.00, 69588.00, 3600, '支付宝', 'delivered', '全国'), (2, 1, '2023-08-20', 8, 6799.00, 54392.00, 3200, '微信支付', 'delivered', '全国'), (3, 2, '2023-09-10', 18, 3799.00, 68382.00, 3600, '支付宝', 'delivered', '全国'), (4, 2, '2023-10-05', 15, 4799.00, 71985.00, 4000, '微信支付', 'delivered', '全国'), (5, 3, '2023-11-01', 20, 7799.00, 155980.00, 8000, '支付宝', 'delivered', '全国'), (6, 3, '2023-12-15', 10, 9799.00, 97990.00, 5000, '微信支付', 'delivered', '全国'); -- 插入商品评价数据 INSERT INTO product_reviews (product_id, rating, review_text, review_date, helpful_votes) VALUES (1, 5, '华为Mate 50拍照真的很棒,性能也很强悍', '2023-10-01', 25), (1, 4, '系统流畅,电池耐用,就是价格有点贵', '2023-10-05', 18), (1, 5, '华为的鸿蒙系统用着很舒服,生态做得不错', '2023-10-08', 32), (2, 5, '华为P60的影像系统太强大了,夜拍效果惊艳', '2023-11-01', 45), (2, 5, '充电速度快,续航给力,值得购买', '2023-11-03', 28), (3, 4, '小米14性价比很高,MIUI优化得不错', '2023-10-15', 20), (3, 3, '拍照一般,充电速度还可以', '2023-10-18', 15), (5, 5, 'iPhone 15的A17芯片性能太强了', '2023-10-25', 50), (5, 4, 'iOS系统稳定,但充电速度有点慢', '2023-10-28', 35), (6, 5, 'iPhone 15 Pro的钛合金边框很漂亮', '2023-11-01', 40), (11, 5, '李宁跑步鞋穿着很舒服,透气性好', '2023-11-10', 22), (11, 4, '鞋子做工精细,适合跑步训练', '2023-11-12', 18), (14, 4, '海尔冰箱制冷效果不错,噪音不大', '2023-06-01', 12), (15, 4, '洗衣机功能齐全,洗净比高', '2023-07-01', 15);
现在我们有了完整的数据,可以进行各种数据分析了。让我们运用学到的SQL聚合和分组知识来进行对电商平台的深入分析:
下面的SQL查询用于对电商平台不同商品类别的销售情况进行全面分析。它统计了每个类别下的商品种类数、总销售数量、总销售额、平均销售单价、最高和最低销售价、参与卖家数以及商品的平均评分。 通过这些指标,可以直观地比较各品类的市场表现、热销程度和用户满意度,从而为运营决策和市场策略提供数据支持。
|-- 分析各类别商品的销售情况 SELECT p.category, COUNT(DISTINCT p.product_id) as product_count, -- 商品种类数 SUM(so.quantity) as total_sales_volume, -- 总销售数量 SUM(so.total_amount) as total_sales_amount, -- 总销售额 AVG(so.unit_price) as avg_selling_price, -- 平均销售单价 MAX(so.unit_price) as highest_price, -- 最高销售价 MIN(so.unit_price) as lowest_price, -- 最低销售价 COUNT(DISTINCT so.seller_id) as seller_count, -- 参与卖家数 AVG(p.rating) as avg_product_rating -- 商品平均评分 FROM products p LEFT JOIN sales_orders so ON p.product_id = so.product_id WHERE p.status = 'active' AND so.order_status = 'delivered' -- 只统计已完成的订单 GROUP BY p.category ORDER BY total_sales_amount DESC;
|+--------------+---------------+--------------------+--------------------+-------------------+---------------+--------------+--------------+--------------------+ | category | product_count | total_sales_volume | total_sales_amount | avg_selling_price | highest_price | lowest_price | seller_count | avg_product_rating | +--------------+---------------+--------------------+--------------------+-------------------+---------------+--------------+--------------+--------------------+ | 电子产品 | 9 | 126 | 777874.00 | 6694.454545 | 9999.00 | 3599.00 |
该SQL查询用于分析电商平台2023年每个月的销售趋势。它通过对销售订单表(sales_orders)和商品表(products)进行关联,按月份(sales_month)分组,统计每月的订单数量、总销售数量、总销售额、毛利润(销售额减去成本)、平均订单金额以及售出的商品种类数。 通过这些指标,可以直观地观察全年各月份的销售波动、季节性变化和盈利能力。
|-- 按月份分析销售趋势 SELECT DATE_FORMAT(order_date, '%Y-%m') as sales_month, COUNT(*) as order_count, -- 订单数量 SUM(quantity) as total_quantity, -- 销售总数量 SUM(total_amount) as total_amount, -- 销售额 SUM(total_amount - (quantity * p.cost_price)) as profit, -- 毛利润 AVG(total_amount)
|+-------------+-------------+----------------+--------------+----------+------------------+----------------------+ | sales_month | order_count | total_quantity | total_amount | profit | avg_order_amount | unique_products_sold | +-------------+-------------+----------------+--------------+----------+------------------+----------------------+ | 2023-01 | 5 | 9 | 46991.00 | 11091.00 | 9398.200000 | 4 | | 2023-02 | 5 | 6
该SQL查询用于分析每个卖家的销售表现。它通过将卖家表(sellers)、销售订单表(sales_orders)和商品表(products)进行关联,统计每个卖家售出的商品种类数、总销售数量、总销售额、平均售价、总利润、所售商品的平均评分以及活跃的月份数。 查询结果只显示有实际销售的卖家(通过HAVING total_sales > 0筛选),并按总销售额从高到低排序。这样可以全面评估各卖家的销售能力、盈利水平和活跃度。
|-- 分析各卖家的销售表现 SELECT s.seller_name, s.seller_type, COUNT(DISTINCT so.product_id) as products_sold, -- 售出商品种类 SUM(so.quantity) as total_quantity, -- 总销售数量 SUM(so.total_amount) as total_sales, -- 总销售额 AVG(
|+-----------------------+-------------+---------------+----------------+-------------+-----------------+--------------+--------------------+---------------+ | seller_name | seller_type | products_sold | total_quantity | total_sales | avg_price | total_profit | avg_product_rating | active_months | +-----------------------+-------------+---------------+----------------+-------------+-----------------+--------------+--------------------+---------------+ | 苹果专卖店 | 企业 | 3 | 42 | 356558.00 | 8956.1428571429 | 60058.00 | 4.842857
该SQL查询用于统计平台上最畅销的前10款商品。它将商品表(products)、销售订单表(sales_orders)和商品评价表(product_reviews)进行关联,计算每个商品的总销量、总销售收入、平均售价、原价、用户平均评分、评价数量以及平均折扣率。 查询结果按照销量从高到低排序,帮助我们快速识别热销商品,并综合分析其销售表现、用户口碑和促销效果。
|-- 商品销售排行榜(TOP 10) SELECT p.product_name, p.category, p.brand, SUM(so.quantity) as total_sold, -- 总销量 SUM(so.total_amount) as total_revenue, -- 总收入 AVG(so.unit_price) as avg_selling_price,
|+-----------------------------+--------------+-----------------+------------+---------------+-------------------+----------------+---------------------+--------------+---------------+ | product_name | category | brand | total_sold | total_revenue | avg_selling_price | original_price | avg_customer_rating | review_count | discount_rate | +-----------------------------+--------------+-----------------+------------+---------------+-------------------+----------------+---------------------+--------------+---------------+ | 华为Mate 50 | 电子产品 | 华为 | 60 | 346740.00 | 5849.000000
该SQL查询用于分析不同地区的销售表现。它统计了每个地区的订单数、总销售数量、总销售额、平均订单金额、销售额占比、商品种类数和卖家数量。 通过这些指标,可以直观了解各地区的市场规模、销售结构和分布差异,为区域市场策略和资源分配提供数据支持。
|-- 按地区分析销售情况 SELECT region, COUNT(*) as order_count, -- 订单数 SUM(quantity) as total_quantity, -- 销售数量 SUM(total_amount) as total_amount, -- 销售额 AVG(total_amount) as avg_order_amount, -- 平均订单金额 SUM(total_amount) * 100.0 / SUM(SUM(total_amount)) OVER () as
|+--------+-------------+----------------+--------------+------------------+------------------+-----------------+----------------+ | region | order_count | total_quantity | total_amount | avg_order_amount | sales_percentage | unique_products | unique_sellers | +--------+-------------+----------------+--------------+------------------+------------------+-----------------+----------------+ | 全国 | 16 | 201 | 704349.00 | 44021.812500 | 83.2969484 | 10 | 5 | |
该SQL查询用于分析不同商品类别的利润率情况。它统计了每个类别下商品的总销量、总收入、总成本和总利润,并进一步计算了平均利润率、最高利润率和最低利润率。 通过这些指标,可以直观了解各品类的盈利能力和利润分布,帮助企业优化产品结构和定价策略。查询还通过HAVING子句筛选出销量较高(销量≥10)的类别,确保分析结果具有代表性和参考价值。
|-- 分析各商品类别的利润率 SELECT p.category, COUNT(DISTINCT p.product_id) as product_count, SUM(so.quantity) as total_sold, SUM(so.total_amount) as total_revenue, -- 总收入 SUM(so.quantity * p.cost_price
|+--------------+---------------+------------+---------------+------------+--------------+-------------------+-------------------+-------------------+ | category | product_count | total_sold | total_revenue | total_cost | total_profit | avg_profit_margin | max_profit_margin | min_profit_margin | +--------------+---------------+------------+---------------+------------+--------------+-------------------+-------------------+-------------------+ | 服装 | 4 | 126 | 38224.00 | 25480.00 | 12744.00 | 34.7314936250 | 39.799331
该SQL查询用于分析不同商品类别的用户评价情况。它统计了每个类别下有评价的商品数量、总评价数、平均评分、最高和最低评分、好评率(4分及以上评价占比)、平均有用票数,以及获得5星评价的商品数。 通过这些指标,可以全面了解各品类的用户满意度、评价活跃度和高分商品分布。
|-- 分析商品评价情况 SELECT p.category, COUNT(DISTINCT p.product_id) as products_with_reviews, COUNT(pr.review_id) as total_reviews, AVG(pr.rating) as avg_rating, MAX(pr.rating) as highest_rating, MIN(
|+--------------+-----------------------+---------------+------------+----------------+---------------+----------------------+-------------------+--------------------+ | category | products_with_reviews | total_reviews | avg_rating | highest_rating | lowest_rating | positive_review_rate | avg_helpful_votes | five_star_products | +--------------+-----------------------+---------------+------------+----------------+---------------+----------------------+-------------------+--------------------+ | 电子产品 | 5 | 10 | 4.5000 | 5 | 3 | 90.00000 |
该SQL语句通过对销售订单和商品表进行关联,按商品类别和月份进行分组,并利用WITH ROLLUP实现多级汇总。查询结果不仅展示了每个类别在每个月的订单数、销售数量、销售总额、平均订单金额、涉及商品数和卖家数,还自动生成了各类别的全年汇总以及全平台的总计数据。
这样可以一目了然地分析各品类、各月份及整体的销售表现和业务概况。
|-- 综合销售分析报告(包含汇总) SELECT COALESCE(category, '总计') as category, COALESCE(month, '全年') as month, order_count, total_quantity, total_amount, ROUND(avg_order_amount, 2) as avg_order_amount, unique_products, unique_sellers FROM ( SELECT p.category, DATE_FORMAT(
|+--------------+---------+-------------+----------------+--------------+------------------+-----------------+----------------+ | category | month | order_count | total_quantity | total_amount | avg_order_amount | unique_products | unique_sellers | +--------------+---------+-------------+----------------+--------------+------------------+-----------------+----------------+ | 家居电器 | 2023-05 | 4 | 10 | 29490.00 | 7372.50 | 4 | 2 | |
|+--------------+---------------+-----------+-----------+ | category | product_count | avg_price | max_price | +--------------+---------------+-----------+-----------+ | 电子产品 | 9 | 7221.22 | 9999.00 | | 家居电器 | 4 | 3124.00 | 3999.00 | | 服装 | 4 | 349.00 | 499.00 | +--------------+---------------+-----------+-----------+
|+-----------------------+-------------+-------------------+-------------+----------------+------------------+ | seller_name | seller_type | registration_year | total_sales | total_quantity | avg_order_amount | +-----------------------+-------------+-------------------+-------------+----------------+------------------+ | 苹果专卖店 | 企业 | 2019 | 356558.00 | 42 | 50936.86 | | 小米之家 | 企业 | 2020 | 209550.00 | 50 | 34925.00 | | 华为官方旗舰店 | 企业 | 2020 | 205767.00 | 33 | 25720.88 | +-----------------------+-------------+-------------------+-------------+----------------+------------------+
|+---------+-------------+---------------+------------------+---------------------+ | month | order_count | monthly_sales | avg_order_amount | growth_rate_percent | +---------+-------------+---------------+------------------+---------------------+ | 2023-01 | 5 | 46991.00 | 9398.20 | NULL | | 2023-02 | 5 | 52994.00 | 10598.80 | 12.77 | | 2023-03 | 6 | 159572.00 | 26595.33 | 201.11 | | 2023-04 | 4 | 11764.00 | 2941.00 | -92.63 | | 2023-05 | 4 | 29490.00 | 7372.50 | 150.68 | | 2023-06 | 4 | 26460.00 | 6615.00 | -10.27 | | 2023-07 | 1 | 69588.00 | 69588.00 | 162.99 | | 2023-08 | 1 | 54392.00 | 54392.00 | -21.84 | | 2023-09 | 1 | 68382.00 | 68382.00 | 25.72 | | 2023-10 | 1 | 71985.00 | 71985.00 | 5.27 | | 2023-11 | 1 | 155980.00 | 155980.00 | 116.68 | | 2023-12 | 1 | 97990.00 | 97990.00 | -37.18 | +---------+-------------+---------------+------------------+---------------------+
|+-----------------+------------+--------------+-------------+------------------+ | product_name | avg_rating | review_count | total_sales | sales_per_review | +-----------------+------------+--------------+-------------+------------------+ | 华为P60 | 5.0 | 6 | 162376.00 | 27062.67 | | iPhone 15 Pro | 5.0 | 3 | 126987.00 | 42329.00 | | 华为Mate 50 | 4.7 | 12 | 346740.00 | 28895.00 | | iPhone 15 | 4.5 | 6 | 419146.00 | 69857.67 | | 李宁跑步鞋 | 4.5 | 4 | 20744.00 | 5186.00 | | 海尔冰箱 | 4.0 | 1 | 7998.00 | 7998.00 | | 海尔洗衣机 | 4.0 | 1 | 2999.00 | 2999.00 | | 小米14 | 3.5 | 6 | 218342.00 | 36390.33 | +-----------------+------------+--------------+-------------+------------------+