Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在mysql中按月分组,即使数据不存在_Mysql - Fatal编程技术网

在mysql中按月分组,即使数据不存在

在mysql中按月分组,即使数据不存在,mysql,Mysql,假设我有一张销售表,如下所示 Customer Date Amount Paul 15/01/2015 2000 Jonathan 15/01/2015 3000 Taylor 15/01/2015 2000 Mark 15/01/2015 3000 Paul 15/02/2015 2000 Jonathan 15/02/2015 3000 Paul 25/02/2015 4000 Jonathan 25/02/2015 5

假设我有一张销售表,如下所示

Customer    Date    Amount
Paul    15/01/2015  2000
Jonathan    15/01/2015  3000
Taylor  15/01/2015  2000
Mark    15/01/2015  3000
Paul    15/02/2015  2000
Jonathan    15/02/2015  3000
Paul    25/02/2015  4000
Jonathan    25/02/2015  5000
Jonathan    15/03/2015  2000
Jonathan    25/04/2015  5000
Taylor  25/04/2015  4000
Mark    25/04/2015  5000
Paul    25/05/2015  4000
Jonathan    25/05/2015  5000
Taylor  25/05/2015  4000
Mark    25/05/2015  5000
在报告中,我希望看到如下所示:

Customer    Month   Amount
Paul    201501  2000
Paul    201502  6000
Paul    201503  0
Paul    201504  0
Paul    201505  4000
请告诉我怎么做

更新

Customer    Month   Amount
Paul    201501  2000
Paul    201502  6000
Paul    201503  0
Paul    201504  0
Paul    201505  4000
Jonathan    201501  3000
Jonathan    201502  8000
Jonathan    201503  2000
Jonathan    201504  5000
Jonathan    201505  5000
Taylor  201501  2000
Taylor  201502  0
Taylor  201503  0
Taylor  201504  4000
Taylor  201505  4000
Mark    201501  3000
Mark    201502  0
Mark    201503  0
Mark    201504  5000
Mark    201505  5000

我还需要为所有客户创建此视图。请告诉我怎么做。

您可以构建一个包含所有月份的在线表格,然后在上面加入您的销售表格

大概是这样的:

SELECT s.customer_name as Customer,
CONCAT(months.m, '-', years.y) as Month,
s.amount as Amount
    FROM (
       SELECT '01' AS m UNION ALL SELECT '02' UNION ALL SELECT '03' UNION ALL 
       SELECT '04' UNION ALL SELECT '05' UNION ALL SELECT '06' UNION ALL 
       SELECT '07' UNION ALL SELECT '08' UNION ALL SELECT '09' UNION ALL 
       SELECT '10' UNION ALL SELECT '11' UNION ALL SELECT '12') AS months
    CROSS JOIN (
       SELECT '2015' AS y UNION ALL SELECT '2016') AS years
    LEFT JOIN sales_table AS s
       ON DATE_FORMAT(s.date, '%Y-%c') = CONCAT(years.y, '-', months.m)
    GROUP BY CONCAT(months.m, '-', years.y)

这是一个解决方案,带有一个演示,使用您提供的日期。此外,还为模拟添加了更多数据

下降表销售

SQL:

输出:

mysql> select * from sales;
+----------+------------+--------+
| Customer | Date       | Amount |
+----------+------------+--------+
| Paul     | 2015-01-15 |   2000 |
| Jonathan | 2015-01-15 |   3000 |
| Taylor   | 2015-01-15 |   2000 |
| Mark     | 2015-01-15 |   3000 |
| Paul     | 2015-02-15 |   2000 |
| Jonathan | 2015-02-15 |   3000 |
| Paul     | 2015-02-25 |   4000 |
| Jonathan | 2015-02-25 |   5000 |
| Jonathan | 2015-03-15 |   2000 |
| Jonathan | 2015-04-15 |   5000 |
| Taylor   | 2015-04-25 |   4000 |
| Mark     | 2015-04-25 |   5000 |
| Paul     | 2015-05-25 |   4000 |
| Jonathan | 2015-05-25 |   5000 |
| Taylor   | 2015-05-25 |   4000 |
| Mark     | 2015-05-25 |   5000 |
+----------+------------+--------+
16 rows in set (0.00 sec)

mysql>
mysql> -- query wanted
mysql> select
    ->     COALESCE(s.Customer, '') AS Customer, DATE_FORMAT(m2.cont_date, '%Y%m') AS Month, SUM(COALESCE(s.Amount, 0)) AS Amount
    -> from (
    ->     select (select MAX(`Date`) from sales) - interval (year.b * 10 + month.a) MONTH AS cont_date
    ->     from (
    ->         select 0 b union select 1 union select 2 union select 3 union select 4 union
    ->         select 5 union select 6 union select 7 union select 8 union select 9) AS year
    ->         CROSS JOIN
    ->         (
    ->         select 0 a union select 1 union select 2 union select 3 union select 4 union
    ->         select 5 union select 6 union select 7 union select 8 union select 9) AS month
    ->     where (year.b * 10 + month.a) < (select timestampdiff(month, MIN(`Date`), MAX(`Date`)) + 1 from sales) ) m2
    ->     LEFT JOIN sales s ON s.Customer = 'paul' AND DATE_FORMAT(m2.cont_date, '%Y%m') = DATE_FORMAT(s.`Date`, '%Y%m')
    -> GROUP BY Month;
+----------+--------+--------+
| Customer | Month  | Amount |
+----------+--------+--------+
| Paul     | 201501 |   2000 |
| Paul     | 201502 |   6000 |
|          | 201503 |      0 |
|          | 201504 |      0 |
| Paul     | 201505 |   4000 |
+----------+--------+--------+
5 rows in set (0.00 sec)

通过queryHi Dylan发布您的群组,谢谢您的回答。当我按客户分组时,因为我的表和月份中有50多个客户,所以应该出现的0不会出现。在您给定的示例中,显示的是201501之后的201410。请让我知道用什么涂抹日期格式。选择日期(格式为“2015-01-15”,“%Y%m”;它返回'201501',我想说的是-根据我们的要求,当金额列中没有一个月的条目时,它应该显示0。但事实上,它没有显示任何价值,也没有跳过这个月。在您给出的示例中,它应该在201411和201412的金额列中显示0,但没有显示任何内容。如您所述,我当前显示的是select union的24个月。我想在amount列中显示没有任何数据的月份-就像问题中的month 201503没有任何数据,但它仍然应该显示在报告中。和月栏中的201503相比,金额应该是0I。我刚刚更新了帖子并扩大了它可以处理的范围。现在它可以处理长达8年,大约100个月。请再试一次。
mysql> select * from sales;
+----------+------------+--------+
| Customer | Date       | Amount |
+----------+------------+--------+
| Paul     | 2015-01-15 |   2000 |
| Jonathan | 2015-01-15 |   3000 |
| Taylor   | 2015-01-15 |   2000 |
| Mark     | 2015-01-15 |   3000 |
| Paul     | 2015-02-15 |   2000 |
| Jonathan | 2015-02-15 |   3000 |
| Paul     | 2015-02-25 |   4000 |
| Jonathan | 2015-02-25 |   5000 |
| Jonathan | 2015-03-15 |   2000 |
| Jonathan | 2015-04-15 |   5000 |
| Taylor   | 2015-04-25 |   4000 |
| Mark     | 2015-04-25 |   5000 |
| Paul     | 2015-05-25 |   4000 |
| Jonathan | 2015-05-25 |   5000 |
| Taylor   | 2015-05-25 |   4000 |
| Mark     | 2015-05-25 |   5000 |
+----------+------------+--------+
16 rows in set (0.00 sec)

mysql>
mysql> -- query wanted
mysql> select
    ->     COALESCE(s.Customer, '') AS Customer, DATE_FORMAT(m2.cont_date, '%Y%m') AS Month, SUM(COALESCE(s.Amount, 0)) AS Amount
    -> from (
    ->     select (select MAX(`Date`) from sales) - interval (year.b * 10 + month.a) MONTH AS cont_date
    ->     from (
    ->         select 0 b union select 1 union select 2 union select 3 union select 4 union
    ->         select 5 union select 6 union select 7 union select 8 union select 9) AS year
    ->         CROSS JOIN
    ->         (
    ->         select 0 a union select 1 union select 2 union select 3 union select 4 union
    ->         select 5 union select 6 union select 7 union select 8 union select 9) AS month
    ->     where (year.b * 10 + month.a) < (select timestampdiff(month, MIN(`Date`), MAX(`Date`)) + 1 from sales) ) m2
    ->     LEFT JOIN sales s ON s.Customer = 'paul' AND DATE_FORMAT(m2.cont_date, '%Y%m') = DATE_FORMAT(s.`Date`, '%Y%m')
    -> GROUP BY Month;
+----------+--------+--------+
| Customer | Month  | Amount |
+----------+--------+--------+
| Paul     | 201501 |   2000 |
| Paul     | 201502 |   6000 |
|          | 201503 |      0 |
|          | 201504 |      0 |
| Paul     | 201505 |   4000 |
+----------+--------+--------+
5 rows in set (0.00 sec)