MySQL销售数据按月平均分组

标签 mysql sql

我有一个包含以下列的销售表:

mysql> select * from sales;
+-------------+--------+------------+
| customer_id | amount | date       |
+-------------+--------+------------+
|           1 |     12 | 2015-01-01 |
|           1 |      1 | 2015-01-02 |
|           1 |    663 | 2015-02-12 |
|           2 |     22 | 2015-01-03 |
|           2 |     21 | 2015-02-12 |
|           2 |     11 | 2015-02-12 |
|           2 |      9 | 2015-04-12 |
+-------------+--------+------------+

我可以使用此查询接近我想要的内容:

SELECT
  customer_id,
  sum(if(month(date) = 1, amount, 0))  AS Jan,
  sum(if(month(date) = 2, amount, 0))  AS Feb,
  sum(if(month(date) = 3, amount, 0))  AS Mar,
  sum(if(month(date) = 4, amount, 0))  AS Apr,
  sum(if(month(date) = 5, amount, 0))  AS May,
  sum(if(month(date) = 6, amount, 0))  AS Jun,
  sum(if(month(date) = 7, amount, 0))  AS Jul,
  sum(if(month(date) = 8, amount, 0))  AS Aug,
  sum(if(month(date) = 9, amount, 0))  AS Sep,
  sum(if(month(date) = 10, amount, 0)) AS Oct,
  sum(if(month(date) = 11, amount, 0)) AS Nov,
  sum(if(month(date) = 12, amount, 0)) AS `Dec`
FROM sales
GROUP BY customer_id;

所需的输出格式:

+-------------+------+------+------+------+------+------+------+------+------+------+------+------+
| customer_id | Jan  | Feb  | Mar  | Apr  | May  | Jun  | Jul  | Aug  | Sep  | Oct  | Nov  | Dec  |
+-------------+------+------+------+------+------+------+------+------+------+------+------+------+
|           1 |   13 |  663 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |
|           2 |   22 |   32 |    0 |    9 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |
+-------------+------+------+------+------+------+------+------+------+------+------+------+------+

但是我想要每月的平均值,当我将 sum 更改为 avg 时,我没有得到平均值。

SELECT
  customer_id,
  avg(if(month(date) = 1, amount, 0))  AS Jan,
  avg(if(month(date) = 2, amount, 0))  AS Feb,
  avg(if(month(date) = 3, amount, 0))  AS Mar,
  avg(if(month(date) = 4, amount, 0))  AS Apr,
  avg(if(month(date) = 5, amount, 0))  AS May,
  avg(if(month(date) = 6, amount, 0))  AS Jun,
  avg(if(month(date) = 7, amount, 0))  AS Jul,
  avg(if(month(date) = 8, amount, 0))  AS Aug,
  avg(if(month(date) = 9, amount, 0))  AS Sep,
  avg(if(month(date) = 10, amount, 0)) AS Oct,
  avg(if(month(date) = 11, amount, 0)) AS Nov,
  avg(if(month(date) = 12, amount, 0)) AS `Dec`
FROM sales
GROUP BY customer_id;

输出(不是每月平均):

+-------------+--------+----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| customer_id | Jan    | Feb      | Mar    | Apr    | May    | Jun    | Jul    | Aug    | Sep    | Oct    | Nov    | Dec    |
+-------------+--------+----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
|           1 | 4.3333 | 221.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 |
|           2 | 5.5000 |   8.0000 | 0.0000 | 2.2500 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 |
+-------------+--------+----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+

我有点疯狂地想弄清楚发生了什么,有人能提供一些建议吗?谢谢

CREATE TABLE `sales` (
  `customer_id` int(11) NOT NULL,
  `amount` int(11) DEFAULT NULL,
  `date` date DEFAULT NULL
) 

INSERT INTO `sales` VALUES (1,12,'2015-01-01'),(1,1,'2015-01-02'),(1,663,'2015-02-12'),(2,22,'2015-01-03'),(2,21,'2015-02-12'),(2,11,'2015-02-12'),(2,9,'2015-04-12');

最佳答案

问题出在0上。它们不会影响 sum(),但会影响平均值。您可以将它们更改为NULL:

SELECT customer_id,
       avg(if(month(date) = 1, amount, NULL))  AS Jan,
       avg(if(month(date) = 2, amount, NULL))  AS Feb,
       avg(if(month(date) = 3, amount, NULL))  AS Mar,
       avg(if(month(date) = 4, amount, NULL))  AS Apr,
       avg(if(month(date) = 5, amount, NULL))  AS May,
       avg(if(month(date) = 6, amount, NULL))  AS Jun,
       avg(if(month(date) = 7, amount, NULL))  AS Jul,
       avg(if(month(date) = 8, amount, NULL))  AS Aug,
       avg(if(month(date) = 9, amount, NULL))  AS Sep,
       avg(if(month(date) = 10, amount, NULL)) AS Oct,
       avg(if(month(date) = 11, amount, NULL)) AS Nov,
       avg(if(month(date) = 12, amount, NULL)) AS `Dec`
FROM sales
GROUP BY customer_id;

请注意:我更喜欢 case 因为它是 ANSI 标准,所以我会将其写为:

       avg(case when month(date) = 1 then amount end) as Jan,

关于MySQL销售数据按月平均分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40039689/

相关文章:

mysql - 根据日期格式统计大表的记录

mysql - 连接两个表两次

sql - 在 SQL Server 中使用 OPTION(MAXDOP 1) 的目的是什么?

mysql - 用于排序排行榜的 SQL 查询

sql - 删除表及其所有依赖项 (Microsoft SQL Server)

c# - DynamicsAX - 按表名获取 SQL 语句

mysql - 加入 has_many :through attributes

mysql - 通过具有多对多关联的 Logstash 将 MySQL 数据迁移到 Elasticsearch

php - CakePHP基于子域选择数据库

sql - MySQL NOT IN Query问题