SQL 选择起始标志之间的行并在几何图形上制作线串

问题描述 投票:0回答:1

我有一个问题,我相信你们专家可以轻松回答:-)

来自 postgresql/postgis 中包含以下内容的表

身份证 |汽车 |时间戳|几何 |开始标志
903 | 903测试1 | 23.11.03 08:38:52 | 0101000020E61000001D33F55 | 4
904 | 904测试1 | 23.11.03 08:39:02 | 0101000020E6100000A40117B | 0
905 | 905测试1 | 23.11.03 08:39:13 | 0101000020E6100000740179C | 0
906 | 906测试1 | 23.11.03 08:39:23 | 0101000020E6100000E68013C | 0
907 | 907测试1 | 23.11.03 08:39:34 | 0101000020E610000014B1886 | 0
908 | 908测试1 | 23.11.03 08:39:44 | 0101000020E61000004309E9D | 4
909 | 909测试1 | 23.11.03 08:39:54 | 0101000020E61000004C6B781 | 0
910 | 910测试1 | 23.11.03 08:40:05 | 0101000020E61000002DC6658 | 0
911 | 911测试1 | 23.11.03 08:40:15 | 0101000020E6100000A0B591A | 0
912 | 912测试1 | 23.11.03 08:40:26 | 0101000020E61000000E1A55E | 0
913 | 913测试1 | 23.11.03 08:40:36 | 0101000020E6100000D7DF128 | 0
914 | 914测试1 | 23.11.03 08:40:46 | 0101000020E61000001C1E673 | 4
915 | 915测试1 | 23.11.03 08:40:57 | 0101000020E6100000DD24068 | 0
916 | 916测试1 | 23.11.03 08:41:07 | 0101000020E6100000CBE48A4 | 0
917 | 917测试1 | 23.11.03 08:41:17 | 0101000020E610000093FFC9D | 0
918 | 918测试1 | 23.11.03 08:41:28 | 0101000020E61000000B3A6B0 | 0

我需要在startflag = 4行之后(并且带有)startflag = 4行的所有记录作为路径(Postgis Linestring over geom)按时间戳排序,直到并且没有下一个startflag = 4

从下一个startflag=4开始,然后是下一个路径,依此类推...

我尝试过引导和分区,但我对此不太了解

postgresql postgis
1个回答
0
投票

一如既往,有几种可能的方法来获得你想要的东西。以下 SQL 语句只是其中之一:

WITH reorder AS (
  SELECT id, car, timestamp
  , row_number() OVER (PARTITION BY car ORDER BY timestamp) AS tcid
  , count(*) OVER (PARTITION BY car) AS max_tcid
  , geom, startflag 
  FROM mytable
), trackranges AS (
  SELECT car, tcid AS tcid_start
  , COALESCE(LEAD(tcid, 1) OVER (partition by car order by timestamp) - 1, max_tcid) AS tcid_last
  FROM reorder
  WHERE startflag = 4
)
SELECT car, tcid_start, ST_MakeLine(geom ORDER BY tcid) AS geom
FROM trackranges AS tr
JOIN reorder AS ro USING (car)
WHERE ro.tcid BETWEEN tr.tcid_start AND tr.tcid_last
GROUP BY car, tcid_start
HAVING count(*) > 1
ORDER BY car, tcid_start;

一些备注:

  • CTE“重新排序”为每辆车分配连续编号,按时间戳排序(“tcid”列)。这实际上是多余的,但稍后使用整数而不是时间戳是我个人的偏好;
  • CTE“重新排序”的要点是添加每辆车的总行数(存储为“max_tcid”),稍后在 COALESCE 函数中使用;
  • CTE“trackranges”选择任何汽车的所有起点(startflag = 4),并使用 LEAD 函数获取该汽车的下一个起点的“tcid”;
  • 当前轨道的最后一个点的 tcid 等于“下一个起始 tcid 减 1”,因此 LEAD 结果需要递减(并且使用“tcid”列中的连续数字序列比使用时间戳要容易得多);
  • 任何汽车的最后一个起点都不会有“下一个起点”(LEAD 函数将返回 NULL,从中减去 1 但仍然产生 NULL),在这种情况下,之前计算的“tcid_last”将发挥作用;
  • CTE“trackranges”因此仅产生 3 列:汽车标识以及用于每个线串的第一个和最后一个“tcid”;
  • 主 SELECT 在汽车识别的基础上连接两个 CTE,使用“trackranges”中的“tcid_start”列来识别每个单独的赛道,仅添加“reorder”中 tcid 在 tcid_start 和 tcid_last 之间的点;
  • 收集的数据按汽车和轨道分组,其几何图形聚合成线串(按 tcid 排序,而 tcid 又按时间戳排序);
  • 如果任何车辆的最后一条记录是新(不完整)轨道的起点,则生成的线串将无效(仅包含单个点)。 HAVING 子句可以防止这种情况,确保只处理具有超过 1 个点的组。
© www.soinside.com 2019 - 2024. All rights reserved.