Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.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_Sql_Performance - Fatal编程技术网

Mysql 按时间聚合

Mysql 按时间聚合,mysql,sql,performance,Mysql,Sql,Performance,我想根据时间间隔聚合mysql数据库中的属性。以下是我的数据结构和一些示例数据: 事件表 +----+---------------------+---------------------+ | id | start | end | +----+---------------------+---------------------+ | 1 | 2017-01-22 14:00:00 | 2017-01-22 17:00:00 | |

我想根据时间间隔聚合mysql数据库中的属性。以下是我的数据结构和一些示例数据:

事件表

+----+---------------------+---------------------+
| id |        start        |         end         |
+----+---------------------+---------------------+
|  1 | 2017-01-22 14:00:00 | 2017-01-22 17:00:00 |
|  2 | 2017-01-22 15:00:00 | 2017-01-22 18:00:00 |
+----+---------------------+---------------------+
+----+----------+--------------+--------+
| id | event_id | person_count | status |
+----+----------+--------------+--------+
|  1 |        1 |            5 |      1 |
|  2 |        1 |            4 |      1 |
|  3 |        1 |            6 |      1 |
|  4 |        2 |            3 |      1 |
|  5 |        2 |            4 |      1 |
|  6 |        2 |            5 |      0 |
+----+----------+--------------+--------+
预订表

+----+---------------------+---------------------+
| id |        start        |         end         |
+----+---------------------+---------------------+
|  1 | 2017-01-22 14:00:00 | 2017-01-22 17:00:00 |
|  2 | 2017-01-22 15:00:00 | 2017-01-22 18:00:00 |
+----+---------------------+---------------------+
+----+----------+--------------+--------+
| id | event_id | person_count | status |
+----+----------+--------------+--------+
|  1 |        1 |            5 |      1 |
|  2 |        1 |            4 |      1 |
|  3 |        1 |            6 |      1 |
|  4 |        2 |            3 |      1 |
|  5 |        2 |            4 |      1 |
|  6 |        2 |            5 |      0 |
+----+----------+--------------+--------+
我正在寻找一种方法,以了解在预订状态为1的15分钟时间间隔内,有多少人(预订总数。人数)参加活动。因此,查询的输出应该如下所示:

+---------------------+--------------------+
|        date         | person_count_total |
+---------------------+--------------------+
| 2017-01-22 14:00:00 |                 15 |
| 2017-01-22 14:15:00 |                 15 |
| 2017-01-22 14:30:00 |                 15 |
| 2017-01-22 14:45:00 |                 15 |
| 2017-01-22 15:00:00 |                 22 |
| 2017-01-22 15:15:00 |                 22 |
| 2017-01-22 15:30:00 |                 22 |
| 2017-01-22 15:45:00 |                 22 |
| 2017-01-22 16:00:00 |                 22 |
| 2017-01-22 16:15:00 |                 22 |
| 2017-01-22 16:30:00 |                 22 |
| 2017-01-22 16:45:00 |                 22 |
| 2017-01-22 17:00:00 |                 22 |
| 2017-01-22 17:15:00 |                  7 |
| 2017-01-22 17:30:00 |                  7 |
| 2017-01-22 17:45:00 |                  7 |
| 2017-01-22 18:00:00 |                  7 |
+---------------------+--------------------+
SELECT 
    t.date,
    SUM(CASE
        WHEN b.status = 1 THEN person_count
    END) person_count_total
FROM
    bookings b
        INNER JOIN
    events e ON b.event_id = e.id
        INNER JOIN
    (SELECT 
        (SELECT 
                    MIN(start)
                FROM
                    events) + INTERVAL 15 * (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a)) MINUTE AS Date
    FROM
        (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a
    CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b
    CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c
    CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS d
) t ON t.date BETWEEN e.start AND e.end
GROUP BY t.date
;

有没有办法只在mysql中实现这一点?当前的解决方案是在php应用程序的第一个开始和最后一个结束之间的15分钟间隔内循环。但是,由于这会创建大量数据点,而且性能不好,因为每个数据点都意味着一个查询。

在日期之间生成行,然后与bookings表进行连接,如下所示:

+---------------------+--------------------+
|        date         | person_count_total |
+---------------------+--------------------+
| 2017-01-22 14:00:00 |                 15 |
| 2017-01-22 14:15:00 |                 15 |
| 2017-01-22 14:30:00 |                 15 |
| 2017-01-22 14:45:00 |                 15 |
| 2017-01-22 15:00:00 |                 22 |
| 2017-01-22 15:15:00 |                 22 |
| 2017-01-22 15:30:00 |                 22 |
| 2017-01-22 15:45:00 |                 22 |
| 2017-01-22 16:00:00 |                 22 |
| 2017-01-22 16:15:00 |                 22 |
| 2017-01-22 16:30:00 |                 22 |
| 2017-01-22 16:45:00 |                 22 |
| 2017-01-22 17:00:00 |                 22 |
| 2017-01-22 17:15:00 |                  7 |
| 2017-01-22 17:30:00 |                  7 |
| 2017-01-22 17:45:00 |                  7 |
| 2017-01-22 18:00:00 |                  7 |
+---------------------+--------------------+
SELECT 
    t.date,
    SUM(CASE
        WHEN b.status = 1 THEN person_count
    END) person_count_total
FROM
    bookings b
        INNER JOIN
    events e ON b.event_id = e.id
        INNER JOIN
    (SELECT 
        (SELECT 
                    MIN(start)
                FROM
                    events) + INTERVAL 15 * (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a)) MINUTE AS Date
    FROM
        (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a
    CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b
    CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c
    CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS d
) t ON t.date BETWEEN e.start AND e.end
GROUP BY t.date
;
如果事件中最小日期和最大日期之间的差异较大,您可以简单地添加另一个交叉连接以适应更多范围,并添加
10000*e.a
。。等等

+---------------------+--------------------+
| date                | person_count_total |
+---------------------+--------------------+
| 2017-01-22 14:00:00 | 15                 |
+---------------------+--------------------+
| 2017-01-22 14:15:00 | 15                 |
+---------------------+--------------------+
| 2017-01-22 14:30:00 | 15                 |
+---------------------+--------------------+
| 2017-01-22 14:45:00 | 15                 |
+---------------------+--------------------+
| 2017-01-22 15:00:00 | 22                 |
+---------------------+--------------------+
| 2017-01-22 15:15:00 | 22                 |
+---------------------+--------------------+
| 2017-01-22 15:30:00 | 22                 |
+---------------------+--------------------+
| 2017-01-22 15:45:00 | 22                 |
+---------------------+--------------------+
| 2017-01-22 16:00:00 | 22                 |
+---------------------+--------------------+
| 2017-01-22 16:15:00 | 22                 |
+---------------------+--------------------+
| 2017-01-22 16:30:00 | 22                 |
+---------------------+--------------------+
| 2017-01-22 16:45:00 | 22                 |
+---------------------+--------------------+
| 2017-01-22 17:00:00 | 22                 | 
+---------------------+--------------------+
| 2017-01-22 17:15:00 | 7                  |
+---------------------+--------------------+
| 2017-01-22 17:30:00 | 7                  |
+---------------------+--------------------+
| 2017-01-22 17:45:00 | 7                  |
+---------------------+--------------------+
| 2017-01-22 18:00:00 | 7                  |
+---------------------+--------------------+

“这会创建很多数据点”。您不需要所有数据点的数据吗?如何避免这种情况?我的意思是,通过php脚本创建数据的成本很高。因为每个数据点意味着一个查询。17:00时的总和不正确,应该是22。因为当时1和2都在场@lasagneYou是对的。我编辑了这个问题