mysql - 使用 MySQL 处理源数据以生成图表摘要

标签 mysql

这是一个 MySql 问题。

我正在分析人们在某个区域花费的时间。

原始数据如下:

visit_id person_id zone_id  timeIn    timeOut
1           1         1     10:58:10  11:03:07
2           1         1     11:03:59  11:04:10
3           2         1     10:52:10  10:53:59
4           2         1     10:57:03  10:57:22
5           2         1     10:57:55  10:58:27
6           2         2     11:04:33  11:05:17

(我在最后添加了MySQL数据定义)

输出是这样的条形图: 对不起。刚刚发现我不能包含图片。这是一个逐分钟的条形图,显示该区域的人数。重要的是,如果该区域在那一分钟内没有人,则显示零条目。如果不存在该要求,那么问题就更加简单。

条形图模块的输入需要如下所示(注意所需的零元素):

zone_id  hourMinute count
1        10:52:00   1
1        10:53:00   1
1        10:54:00   0
1        10:55:00   0
1        10:56:00   0
1        10:57:00   1
1        10:58:00   2
1        10:59:00   1
1        11:00:00   1
1        11:01:00   1
1        11:02:00   1
1        11:03:00   1
1        11:04:00   1
2        10:52:00   0
2        10:53:00   0
2        10:54:00   0
2        10:55:00   0
2        10:56:00   0
2        10:57:00   0
2        10:58:00   0
2        10:59:00   0
2        11:00:00   0
2        11:01:00   0
2        11:02:00   0
2        11:03:00   0
2        11:04:00   1
2        11:05:00   1

此外,上面的原始数据适用于两个条形图(区域 1 和区域 2)。我只显示了区域 1 的图表。

我可以通过在数据库和后端脚本之间来回传输数据来分多个阶段创建数据,但这很麻烦、难以支持且效率低下。

我怀疑一定可以在 mysql 中完成这一切,但我自己没有足够的能力实现这一点。

任何人都可以显示从输入到所需输出所需的mysql吗?

谢谢!

<小时/>

附录:

如果有助于理解问题,我在数据库和后端创建的中间结构如下:

流程1:突破

visit_id    person_id zone_id hourMinute
1           1         1       10:58:00
1           1         1       10:59:00
1           1         1       11:00:00
1           1         1       11:01:00
1           1         1       11:02:00
1           1         1       11:03:00
2           1         1       11:03:00
2           1         1       11:04:00
3           2         1       10:52:00
3           2         1       10:53:00
4           2         1       10:57:00
5           2         1       10:57:00
5           2         1       10:58:00
6           2         2       11:04:00
6           2         2       11:05:00

流程02:按小时排序

visit_id    person_id zone_id hourMinute
3           2         1       10:52:00
3           2         1       10:53:00
4           2         1       10:57:00
5           2         1       10:57:00
1           1         1       10:58:00
5           2         1       10:58:00
1           1         1       10:59:00
1           1         1       11:00:00
1           1         1       11:01:00
1           1         1       11:02:00
1           1         1       11:03:00
2           1         1       11:03:00
2           1         1       11:04:00
6           2         2       11:04:00
6           2         2       11:05:00

流程03:计数

zone_id     hourMinute  count   
1           10:52:00    1   
1           10:53:00    1   
1           10:57:00    1   
1           10:58:00    2   
1           10:59:00    1   
1           11:00:00    1   
1           11:01:00    1   
1           11:02:00    1   
1           11:03:00    1   person_id 1 visited twice in same minute
1           11:04:00    1   
2           11:04:00    1   
2           11:05:00    1   

输入数据定义

CREATE DATABASE  IF NOT EXISTS `test` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `test`;
-- MySQL dump 10.13  Distrib 5.6.11, for Win32 (x86)
--
-- Host: localhost    Database: test
-- ------------------------------------------------------
-- Server version   5.6.14

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `tb_stackoverflowquestion01`
--

DROP TABLE IF EXISTS `tb_stackoverflowquestion01`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tb_stackoverflowquestion01` (
  `visit_id` int(11) NOT NULL AUTO_INCREMENT,
  `person_id` int(11) DEFAULT NULL,
  `zone_id` int(11) DEFAULT NULL,
  `timeIn` datetime DEFAULT NULL,
  `timeOut` datetime DEFAULT NULL,
  PRIMARY KEY (`visit_id`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8 COMMENT='Question asked here:\nhttp://stackoverflow.com/questions/19723032/processing-source-data-to-produce-chartable-summary-with-mysql';
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `tb_stackoverflowquestion01`
--

LOCK TABLES `tb_stackoverflowquestion01` WRITE;
/*!40000 ALTER TABLE `tb_stackoverflowquestion01` DISABLE KEYS */;
INSERT INTO `tb_stackoverflowquestion01` VALUES (16,1,1,'2013-01-01 10:58:10','2013-01-01 11:03:07'),(17,1,1,'2013-01-01 11:03:59','2013-01-01 11:04:10'),(18,2,1,'2013-01-01 10:52:10','2013-01-01 10:53:59'),(19,2,1,'2013-01-01 10:57:03','2013-01-01 10:57:22'),(20,2,1,'2013-01-01 10:57:55','2013-01-01 10:58:27'),(21,2,2,'2013-01-01 11:04:33','2013-01-01 11:05:17');
/*!40000 ALTER TABLE `tb_stackoverflowquestion01` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Dumping routines for database 'test'
--
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2013-11-01  8:36:33

从现在开始,下一步是页面顶部显示的最终输出

最佳答案

我坚持下来并自己创建了解决方案:

简而言之,我创建了一个日期表,其中包含 future 50 年的所有可能日期(射击我)。

然后创建了一个时间表,其中包含 24 小时内所有可能的时间(以分钟为间隔)(再次拍摄我)。

然后进行笛卡尔连接,以在所考虑的集合的上限和下限内创建日期/时间列表,并在日期时间位于原始记录限制内时将其与原始数据进行左侧连接。

然后分组并计数。

不确定处理数十万条记录的速度有多快,但我怀疑比在数据库和后端之间来回传递要好。

任何提高性能或增加优雅的提示或提示,我们深表感谢:)

zone_id 1 的 SQL 如下:

select dateTimeC, count(zone_id)
from 
    (
        SELECT dateTimeC, tb_stackoverflowquestion01.zone_id, person_id 
        FROM 
            (
                SELECT 
                    addTime(date, time) as dateTimeC,
                    zone_id
                FROM tb_date, tb_time, tb_stackoverflowquestion01

                where tb_date.date >= 
                    (
                        select date(min(timeIn))
                        from  tb_stackoverflowquestion01
                        where zone_id = 1 
                    )
                and tb_date.date <= 
                    (
                        select date(max(timeOut))
                        from  tb_stackoverflowquestion01
                        where zone_id = 1 
                    )
                and time >= 
                    (
                        select time(addTime(min(timein),-second(min(timeIn))))
                        from  tb_stackoverflowquestion01
                        where zone_id = 1 
                    )
                and time <= 
                    (
                        select time(max(timeOut))
                        from  tb_stackoverflowquestion01
                        where zone_id = 1 
                    )

                group by dateTimeC
            ) as t1
        left join tb_stackoverflowquestion01
        on  dateTimeC >= addTime(timein, -second((timeIn)))
        and dateTimeC <= timeOut
        and t1.zone_id = tb_stackoverflowquestion01.zone_id

        group by dateTimeC, zone_id, person_id
    ) as t2
group by dateTimeC

关于mysql - 使用 MySQL 处理源数据以生成图表摘要,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19723032/

相关文章:

mysql - 如何使用数据列表使用 FIND_IN_SET

Mysql 查询检索关系表中缺失的组合

MySQL表被标记为crashed,如何通过查询得到crashed表

mysql - 如何创建所有列都不是 NULL 的 MySQL 表?

php - MySQL查询涉及3个表和2个数据库,无法获取正确的列

php - mysql IN 运算符按降序返回值

php - mysql_error() 不显示错误

MySql:在记录不存在的情况下两次连接同一个表

sql - 获取SQL中两次之间的平均时间

mysql - 从亚马逊ubuntu 10.04实例连接到Windows Server 2003中的Oracle数据库