mysql—按出行方式划分的gps点数

zpqajqem  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(345)

我正在研究 geolife 数据集。这是一个 GPS 近25m轨迹数据集 GPS 用户点。所以我创建了两个表(实际上是从这里复制的): plt_distinct 包含用户的gps点(超过24m行)和 labels 包含参与者使用的旅行模式的表格(14718行)。

CREATE TABLE `plt_distinct` (
  `directory` varchar(10) NOT NULL DEFAULT '',
  `latitude` double NOT NULL DEFAULT '0',
  `longitude` double NOT NULL DEFAULT '0',
  `flag` int(11) DEFAULT NULL,
  `altitude` double NOT NULL DEFAULT '0',
  `passeddate` varchar(255) DEFAULT NULL,
  `gpsdate` date NOT NULL DEFAULT '0000-00-00',
  `gpstime` time NOT NULL DEFAULT '00:00:00',
  `gpsdatetime` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`directory`,`latitude`,`longitude`,`gpsdate`,`gpstime`,`altitude`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `labels` (
  `directory` varchar(10) NOT NULL DEFAULT '',
  `starttime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `endtime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `transportationmode` varchar(10) NOT NULL DEFAULT '',
  PRIMARY KEY (`directory`,`starttime`,`endtime`,`transportationmode`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我要做一些探索性的分析(比如 GPS 每个行驶模式的采样率等…)。如中所述,用户有大约10种不同的出行方式 labels .
因此,首先,我想计算每个旅行模式的gps点数,因此我写下:

SELECT COUNT(*) 
FROM labels JOIN plt_distinct 
USING (directory) 
WHERE transportationmode='bus';

+------------+
| COUNT(*)   |
+------------+
| 1881761963 |
+------------+
1 row in set (7 min 13.83 sec)

这个查询返回超过188m个计数,这显然超过了一个亿,大约是所有可用gps点的80倍。我知道我做的事情不对(公共汽车模式不计算不同的点),但我不确定如何实现我的目标。
为了解决我的问题(说明我的意思),我在这里创建了一个db fiddle,其中只有5行 tables (只有2个) bus 旅行模式),但我的查询返回10的计数。
如何正确计算每个旅行模式的点数?

ne5o7dgx

ne5o7dgx1#

过度放任导致的组合爆炸 ON a中的子句 JOIN .
在你的小提琴里,你的 labels 示例包含这些行。

directory | starttime           | endtime             | transportationmode
:-------- | :------------------ | :------------------ | :-----------------
179       | 2008-11-17 06:59:58 | 2008-11-17 07:06:16 | bus               
179       | 2008-11-17 07:06:16 | 2008-11-17 07:14:32 | walk              
179       | 2008-11-29 02:01:39 | 2008-11-29 02:07:57 | walk              
179       | 2008-11-29 02:07:57 | 2008-11-29 02:01:39 | bus               
179       | 2008-11-29 02:07:57 | 2008-11-29 02:43:37 | subway

注意 transportationmode 列包含的值重复 bus 以及 walk 同样的价值 directory . 那意味着你的

FROM plt_distinct JOIN labels ON plt_distinct.directory = labels.directory

子句把每一行都拉进来 plt_distinct 五次,每行一次 labels . 那就意味着排得太多了。
我想,不确定的是 plt_distinct 应仅与中的一行关联 labels . 您可以通过匹配时间戳和目录来实现这一点(你的第二个 labels.bus 列的结束时间早于开始时间,因此很难确定。)
使用类似于这样的on子句的查询可以做到这一点。

SELECT *
  FROM labels 
  JOIN plt_distinct ON labels.directory = plt_distinct.directory
                   AND plt_distinct.gpsdatetime >= labels.starttime
                   AND plt_distinct.gpsdatetime <= labels.endtime;

但两者之间没有太多重叠 gpsdatetime 价值观和 starttime / endtime 价值观,所以我不确定这是否正确。
你的数据需要一种方法 labels 每行 plt_distinct 如果此项目要工作,请单击“行”。
专业提示避免 USING(column)JOIN 条款。它很容易出错。

相关问题