如何从 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 BY
列 loc
,在每个组内按 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) |
+---------------------------------+
可重现的设置
我有一个(示例)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 BY
列 loc
,在每个组内按 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) |
+---------------------------------+