【问题标题】:Fetching Total Sale of each day and month from database从数据库中获取每天和每月的总销售额
【发布时间】:2013-10-21 20:39:24
【问题描述】:

我有一个表,其中c_date 列为datetimetotalint 输入mysql,我想打印每天的销售额,每月的总销售额,以及每年的总销售额,包括没有销售的日、月、年。

目前每天销售,我正在运行以下查询:

mysql> select date(c_date) as date, sum(total) as total_sale from sale group by date;
+------------+------------+
| date       | total_sale |
+------------+------------+
| 2013-10-3  |        798 |
| 2013-10-6  |        114 |
+------------+------------+

但是,我想要这样的东西:

mysql> select date(c_date) as date, sum(total) as total_sale from sale group by date;
+------------+------------+
| date       | total_sale |
+------------+------------+
| 2013-10-1  |          0 |
| 2013-10-2  |          0 |
| 2013-10-3  |        798 |
| 2013-10-4  |          0 |
| 2013-10-5  |          0 |
| 2013-10-6  |        114 |
+------------+------------+

对于每月,我得到了这个:

mysql> select c_date, month(c_date) as month, year(c_date) as year, sum(total) as total from sale group by c_date order by c_date;
+---------------------+-------+------+-------+
| c_date              | month | year | total |
+---------------------+-------+------+-------+
| 2013-10-3 02:40:06  |    10 | 2013 |   228 |
| 2013-10-3 02:41:58  |    10 | 2013 |   114 |
| 2013-10-3 02:44:36  |    10 | 2013 |   114 |
| 2013-10-3 02:46:40  |    10 | 2013 |   114 |
| 2013-10-3 02:49:15  |    10 | 2013 |   114 |
| 2013-10-3 02:53:36  |    10 | 2013 |   114 |
| 2013-10-6 07:43:27  |    10 | 2013 |   114 |
+---------------------+-------+------+-------+

但我想要这样的东西:

mysql> select c_date, month(c_date) as month, year(c_date) as year, sum(total) as total from sale group by c_date order by c_date;
+---------------------+-------+------+-------+
| c_date              | month | year | total |
+---------------------+-------+------+-------+
| 2013-1-3 02:40:06   |     1 | 2013 |     0 |
| 2013-2-3 02:41:58   |     2 | 2013 |     0 |
| 2013-3-3 02:44:36   |     3 | 2013 |     0 |
| 2013-4-3 02:46:40   |     4 | 2013 |     0 |
| 2013-5-3 02:49:15   |     5 | 2013 |     0 |
| 2013-6-3 02:53:36   |     6 | 2013 |     0 |
| 2013-7-6 07:43:27   |     7 | 2013 |     0 |
| 2013-8-3 02:44:36   |     8 | 2013 |     0 |
| 2013-9-3 02:46:40   |     9 | 2013 |     0 |
| 2013-10-3 02:49:15  |    10 | 2013 |   912 |
| 2013-11-3 02:53:36  |    11 | 2013 |     0 |
| 2013-12-6 07:43:27  |    12 | 2013 |     0 |
+---------------------+-------+------+-------+

Mysql 可以做到这一点吗?

【问题讨论】:

  • 啊,有趣的 SQL 问题之一。我通常会通过设置一个包含所有日期的表并使用左外连接从它加入。但是很好奇人们会想出什么。
  • 每天有单独的表格是一种选择,但这可能吗?无需创建另一个表
  • 这个问题没有任何公认的答案,如果你知道如何解决这个添加答案,这可能对 OP 有所帮助。

标签: mysql sql


【解决方案1】:

由于在 MySQL 中无法使用 sequences(实际上它们根本不存在),因此您必须先创建日期范围表。就像这样:

CREATE TABLE dates_range (record_date DATE)

然后用日期填充此表,从日期中的最小值开始,存在于您的 sale 表中,直到最大值。

之后,使用 SQL LEFT JOIN 运算符,您将能够像这样聚合数据:

SELECT
  YEAR(dates_range.record_date),
  MONTH(dates_range.record_date),
  DAY(dates_range.record_date),
  COALESCE(SUM(sale.total), 0) AS total_sum
FROM
  dates_range
    LEFT JOIN sale
      ON dates_range.record_date=DATE(sale.c_date)
GROUP BY
  YEAR(dates_range.record_date),
  MONTH(dates_range.record_date),
  DAY(dates_range.record_date)

【讨论】:

  • 运行您的查询后我得到空结果集
  • @JohnCargo 你必须填写你的 dates_range 表。如果您将其留空,那么这将是您的结果
  • 你的意思是,我需要填写0-30天的数据吗?
  • sale 表中的最小日期到最大日期的所有日期
  • 在 MySQL 中没有其他方法(我已经通过指出“MySQL 中没有序列”来提到这一点)。另一种方法是在您的应用程序中执行此操作。
【解决方案2】:

在我看来,您需要与日历表进行外部联接。

想象一个日历表填充如下:

日历

Year Month   Day
2013 201310  2013-10-1    
2013 201310  2013-10-2
...

然后你可以写一个类似的查询

         select date(c_day) as date, 
                sum(total) as total_sale 
           from calendar c 
left outer join sale s 
             on c.day = s.c_date
          where c.month = 201310
       group by c_day
         having c_day <= max(s.c_date); -- this is to avoid to show all 
                                        -- days for October

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 2020-02-21
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 1970-01-01
    相关资源
    最近更新 更多