【问题标题】:mysql display each type in row and group by date rangemysql按日期范围显示行中的每种类型并分组
【发布时间】:2017-01-09 03:41:44
【问题描述】:

我不确定这个数据结构能否达到我想要的结果。 http://sqlfiddle.com/#!9/84939

这是数据,请忽略持续时间列。

+----+---------------------+---------------------+---------------------+----------+--------+------+
| id | created_date        | start_date          | end_date            | duration | status | type |
+----+---------------------+---------------------+---------------------+----------+--------+------+
|  1 | 2016-04-05 15:23:29 | 2016-08-15 10:21:53 | 2016-08-19 00:00:00 |       30 |      1 |    2 |
|  2 | 2016-04-06 15:23:29 | 2016-08-15 10:21:53 | 2016-08-19 00:00:00 |       30 |      1 |    1 |
|  3 | 2016-04-06 15:23:29 | 2016-08-15 10:21:53 | 2016-08-19 00:00:00 |       30 |      1 |    3 |
|  4 | 2016-04-06 15:23:29 | 2016-08-17 10:21:53 | 2016-08-19 00:00:00 |       30 |      1 |    1 |
|  5 | 2016-04-06 15:23:29 | 2016-08-17 09:21:53 | 2016-08-19 00:00:00 |       30 |      1 |    1 |
|  6 | 2016-04-06 15:23:29 | 2016-08-01 09:21:53 | 2016-08-31 00:00:00 |       30 |      1 |    1 |
|  7 | 2016-04-06 15:23:29 | 2016-08-01 09:21:53 | 2016-08-31 00:00:00 |       30 |      0 |    1 |
|  8 | 2016-04-06 15:23:29 | 2016-08-15 09:21:53 | 2016-08-16 00:00:00 |       30 |      1 |    2 |
|  9 | 2016-04-06 15:23:29 | 2016-08-16 09:21:53 | 2016-08-17 00:00:00 |       30 |      1 |    3 |
| 10 | 2016-04-06 15:23:29 | 2016-08-19 09:21:53 | 2016-08-20 00:00:00 |       30 |      1 |    2 |
+----+---------------------+---------------------+---------------------+----------+--------+------+

我想过滤从 2016 年 8 月 15 日到 2016 年 8 月 19 日的报告。对于 2015-08-19 甚至 00:00:00,我不确定是否考虑计数。但对于我的例子。我只是计算它,因为它在范围内。 这是我手动完成的总结:-

(type-2)15,16,17,18,19
(type-1)15,16,17,18,19
(type-3)15,16,17,18,19
(type-1)17,18,19
(type-1)17,18,19
(type-1)15,16,17,18,19
(type-1)15,16,17,18,19
(type-2)15,16
(type-3)16,17
(type-2)19,20

这是我想在 sql 返回数据中生成的结果。

+------------+--------+-----------+-----------+-----------+
| date       | ct_all | ct_type_1 | ct_type_2 | ct_type_3 |
+------------+--------+-----------+-----------+-----------+
| 2016-08-15 | 6      | 3         | 2         | 1         |
| 2016-08-16 | 7      | 3         | 2         | 2         |
| 2016-08-17 | 8      | 5         | 1         | 2         |
| 2016-08-18 | 7      | 5         | 1         | 1         |
| 2016-08-19 | 8      | 5         | 2         | 1         |
+------------+--------+-----------+-----------+-----------+

ct_all = 全部计数

ct_type_1 = 类型 1 的总数

只要类型落在 start_date 和 end_date 中,它就会被计算在内。 通常我们完成的搜索日期基于一种列类型,例如 created_date。我可以在 >= 和

【问题讨论】:

标签: mysql datetime count pivot-table


【解决方案1】:

这里发生了三种不同的事情。

  1. 天数。
  2. DATETIME 范围过滤器。
  3. 所谓的枢轴,将行按类型旋转到列中。

一次服用这些很有帮助。

首先,我想您有五天要过滤,包括 [2016 年 8 月 15 日 - 2016 年 8 月 19 日]。你想列出所有这些日子。这个小查询将做到这一点。 (http://sqlfiddle.com/#!9/84939/21/0)

    SELECT CONVERT('2016-08-15' + INTERVAL seq DAY, DATETIME) AS CURDATE
        FROM (SELECT 0 AS SEQ UNION ALL SELECT 1 UNION ALL SELECT 2
                              UNION ALL SELECT 3 UNION ALL SELECT 4
             ) seq_0_to_4

(请注意:MariaDB fork of MySQL 具有 sequence tables like seq_0_to_4 built in,因此您不必做所有这些 UNION ALL 的事情。)

其次,您想要获取每天发生的type 值的列表。您可以通过 LEFT JOIN 实现这一点,就像这样 (http://sqlfiddle.com/#!9/84939/26/0)。

 SELECT seq.curdate, record.type
   FROM (

          SELECT CONVERT('2016-08-15' + INTERVAL seq DAY, DATETIME) AS CURDATE
            FROM (SELECT 0 AS SEQ UNION ALL SELECT 1 UNION ALL SELECT 2
                                  UNION ALL SELECT 3 UNION ALL SELECT 4
                 ) seq_0_to_4
       ) seq
  LEFT JOIN record ON seq.curdate >= DATE(record.start_date)
                  AND seq.curdate <= DATE(record.end_date)

这将为您提供curdatetype 值的列表。

该联接的ON 条件选择record 在每个日期或之前开始并在每个日期的任何时间结束的行。

最后,您需要执行pivot 操作来汇总类型值的计数。看起来像这样。 (http://sqlfiddle.com/#!9/84939/28/0)

 SELECT curdate, 
        COUNT(type) ct_all,
        SUM(CASE WHEN type = 1 THEN 1 ELSE 0 END) ct_1,
        SUM(CASE WHEN type = 2 THEN 1 ELSE 0 END) ct_2,
        SUM(CASE WHEN type = 3 THEN 1 ELSE 0 END) ct_3
   FROM (the above query) d
  GROUP BY curdate
  ORDER BY curdate

这是结构化查询语言的结构化部分是必要的情况。

【讨论】:

  • 我无法想象它可以做到。 seq_0_to_4 我从mysql知识中学到的一些新东西。谢谢奥利琼斯!你的解释太棒了!赞赏!
猜你喜欢
  • 2015-01-22
  • 2010-10-31
  • 2019-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-19
  • 2013-08-14
  • 1970-01-01
相关资源
最近更新 更多