如何从 BigQuery 中的有序 groupbyed 点创建线?

How to create lines from ordered groupbyed points in BigQuery?

可重现的设置

我有一个(示例)BigQuery table,project.table.geodata

CREATE OR REPLACE TABLE `project.table.geodata` AS (
  SELECT ST_GEOGPOINT(70., 12.) AS geometry, 'a' AS loc, 1 as timestamp
   UNION ALL
  SELECT ST_GEOGPOINT(70., 14.) AS geometry, 'a' AS loc, 2 as timestamp
   UNION ALL
  SELECT ST_GEOGPOINT(72., 14.) AS geometry, 'a' AS loc, 3 as timestamp
    UNION ALL
  SELECT ST_GEOGPOINT(55., 24.) AS geometry, 'b' AS loc, 4 as timestamp
    UNION ALL
  SELECT ST_GEOGPOINT(55., 26.) AS geometry, 'b' AS loc, 5 as timestamp
    UNION ALL
  SELECT ST_GEOGPOINT(57., 26.) AS geometry, 'b' AS loc, 8 as timestamp
)

可视化:


想要的结果

我想将具有相同 loc 的点组合在一起,并从它们创建一条线,通过递增 timestamp 对它们进行排序。

手动创建预期输出:

CREATE OR REPLACE TABLE `project.table.lines` AS (
  SELECT ST_GeogFromText('LINESTRING(70 12, 70 14, 72 14)') as line
    UNION ALL
  SELECT ST_GeogFromText('LINESTRING(55 24, 55 26, 57 26)') as line
)

看起来像:

这些行具有 GEOGRAPHY 数据类型。


我试过的

我想我应该 GROUP BYloc,在每个组内按 timestamp 排序,然后从结果数组创建线串。

我想到了:

select st_makeline(array_agg(geometry)) as lines from `project.table.geodata` group by loc;

但这并不能保证点的顺序随着线内相关 timestamp 值的增加而增加。


问题

什么 SQL 查询产生所需的输出?

你似乎接近答案了。只需在 ARRAY_AGG 中添加 ORDER BY 子句即可。

WITH geodata AS (
  SELECT ST_GEOGPOINT(70., 12.) AS geometry, 'a' AS loc, 1 as timestamp
   UNION ALL
  SELECT ST_GEOGPOINT(70., 14.) AS geometry, 'a' AS loc, 2 as timestamp
   UNION ALL
  SELECT ST_GEOGPOINT(72., 14.) AS geometry, 'a' AS loc, 3 as timestamp
    UNION ALL
  SELECT ST_GEOGPOINT(55., 24.) AS geometry, 'b' AS loc, 4 as timestamp
    UNION ALL
  SELECT ST_GEOGPOINT(55., 26.) AS geometry, 'b' AS loc, 5 as timestamp
    UNION ALL
  SELECT ST_GEOGPOINT(57., 26.) AS geometry, 'b' AS loc, 8 as timestamp
)
SELECT ST_MAKELINE(ARRAY_AGG(geometry ORDER BY timestamp)) AS lines 
  FROM geodata GROUP BY loc;

output:
+---------------------------------+
|              lines              |
+---------------------------------+
| LINESTRING(70 12, 70 14, 72 14) |
| LINESTRING(55 24, 55 26, 57 26) |
+---------------------------------+