Я применяю порядок, в котором геометрия содержится в GEOMETRYCOLLECTION
, объединяя wkt и используя STUFF
с ORDER BY
(я использую SQL Server 2016, в противном случае я бы использовал STRING_AGG )
DECLARE @OrderedGeometryList TABLE
(
[GroupId] INT,
[Geometry] GEOMETRY,
[Order] INT
)
INSERT @OrderedGeometryList
VALUES
(1, 'LINESTRING(3 3, 4 4)', 3)
,(1, 'LINESTRING(0 0, 1 1)', 1)
,(1, 'LINESTRING(1 1, 2 2)', 2)
,(2, 'POINT(35453 141)', 2)
,(2, 'MULTILINESTRING((0 0, 1 1),(2 2, 3 3))', 1)
Тогда
;WITH Grouped AS (
SELECT
[GroupId]
,Geometry::STGeomCollFromText(
'GEOMETRYCOLLECTION(' +
STUFF((
SELECT ',' + [Geometry].ToString()
FROM @OrderedGeometryList t2
WHERE t1.[GroupId] = t2.[GroupId]
ORDER BY [Order]
FOR XML PATH ('')
), 1, 1, '')
+ ')', MAX([Geometry].STSrid)
) as [Geometry]
FROM @OrderedGeometryList t1
GROUP BY [GroupId]
)
SELECT GroupId, Geometry.ToString() as WKT
FROM Grouped
Выдает:
GroupId WKT
1 GEOMETRYCOLLECTION (LINESTRING (0 0, 1 1), LINESTRING (1 1, 2 2), LINESTRING (3 3, 4 4))
2 GEOMETRYCOLLECTION (MULTILINESTRING ((0 0, 1 1), (2 2, 3 3)), POINT (35453 141))
Обратите внимание, как порядок сбора (слева направо) соответствует порядку, указанному в таблице. Это эффект, которого я добиваюсь, но мне любопытно, есть ли более чистый способ сделать это.
Я подумал о том, чтобы написать свой собственный агрегат CLR, а затем использовать OVER()
с ORDER BY
, но, похоже, это не поддерживается Можно ли использовать определенные пользователем агрегаты (clr) с оконными функциями (более)?