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

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

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

  1. CREATE TABLE `plt_distinct` (
  2. `directory` varchar(10) NOT NULL DEFAULT '',
  3. `latitude` double NOT NULL DEFAULT '0',
  4. `longitude` double NOT NULL DEFAULT '0',
  5. `flag` int(11) DEFAULT NULL,
  6. `altitude` double NOT NULL DEFAULT '0',
  7. `passeddate` varchar(255) DEFAULT NULL,
  8. `gpsdate` date NOT NULL DEFAULT '0000-00-00',
  9. `gpstime` time NOT NULL DEFAULT '00:00:00',
  10. `gpsdatetime` timestamp NULL DEFAULT NULL,
  11. PRIMARY KEY (`directory`,`latitude`,`longitude`,`gpsdate`,`gpstime`,`altitude`)
  12. ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
  13. CREATE TABLE `labels` (
  14. `directory` varchar(10) NOT NULL DEFAULT '',
  15. `starttime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  16. `endtime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  17. `transportationmode` varchar(10) NOT NULL DEFAULT '',
  18. PRIMARY KEY (`directory`,`starttime`,`endtime`,`transportationmode`)
  19. ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

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

  1. SELECT COUNT(*)
  2. FROM labels JOIN plt_distinct
  3. USING (directory)
  4. WHERE transportationmode='bus';
  5. +------------+
  6. | COUNT(*) |
  7. +------------+
  8. | 1881761963 |
  9. +------------+
  10. 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 示例包含这些行。

  1. directory | starttime | endtime | transportationmode
  2. :-------- | :------------------ | :------------------ | :-----------------
  3. 179 | 2008-11-17 06:59:58 | 2008-11-17 07:06:16 | bus
  4. 179 | 2008-11-17 07:06:16 | 2008-11-17 07:14:32 | walk
  5. 179 | 2008-11-29 02:01:39 | 2008-11-29 02:07:57 | walk
  6. 179 | 2008-11-29 02:07:57 | 2008-11-29 02:01:39 | bus
  7. 179 | 2008-11-29 02:07:57 | 2008-11-29 02:43:37 | subway

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

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

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

  1. SELECT *
  2. FROM labels
  3. JOIN plt_distinct ON labels.directory = plt_distinct.directory
  4. AND plt_distinct.gpsdatetime >= labels.starttime
  5. AND plt_distinct.gpsdatetime <= labels.endtime;

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

展开查看全部

相关问题