STNumGeometries: примеры (SQL)
STNumGeometries: intОписание функции STNumGeometries
Функция STNumGeometries() является методом типа данных geometry в Microsoft SQL Server. Она возвращает количество геометрических объектов, содержащихся в экземпляре geometry. Основное применение функции связано с мультигеометрическими типами, такими как MultiPoint, MultiLineString, MultiPolygon и GeometryCollection.
Метод не принимает параметров и вызывается для конкретного экземпляра геометрического объекта. Синтаксис вызова: geometry_instance.STNumGeometries().
Возвращаемое значение имеет тип int. Функция возвращает:
- 1 для простых геометрических типов (Point, LineString, Polygon)
- Число больше 1 для мультигеометрических типов
- NULL, если экземпляр geometry является NULL
Функция доступна начиная с SQL Server 2008 и поддерживается во всех последующих версиях.
Базовые примеры использования
Пример с простой геометрией:
DECLARE @point geometry = geometry::STGeomFromText('POINT(10 20)', 0);
SELECT @point.STNumGeometries() AS NumberOfGeometries;NumberOfGeometries ------------------ 1
Пример с мультиточкой:
DECLARE @multiPoint geometry = geometry::STGeomFromText('MULTIPOINT((10 20), (30 40), (50 60))', 0);
SELECT @multiPoint.STNumGeometries() AS NumberOfGeometries;NumberOfGeometries ------------------ 3
Пример с коллекцией геометрий:
DECLARE @collection geometry = geometry::STGeomFromText('GEOMETRYCOLLECTION(POINT(10 20), LINESTRING(0 0, 10 10), POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)))', 0);
SELECT @collection.STNumGeometries() AS NumberOfGeometries;NumberOfGeometries ------------------ 3
Похожие функции в MS SQL Server
В MS SQL Server существуют другие функции для работы с геометрическими объектами:
- STGeometryN(индекс) возвращает конкретную геометрию из мультигеометрического объекта по указанному индексу (начинается с 1). Эта функция полезна для извлечения отдельных компонентов.
- STNumPoints() возвращает общее количество точек в геометрическом объекте, включая все его компоненты.
- STNumCurves() специфична для типов данных geometry и geography, возвращает количество кривых в объекте.
Функцию STNumGeometries предпочтительнее использовать для получения количества компонентов в мультигеометрических объектах, в то время как STGeometryN применяют для доступа к конкретным компонентам.
Альтернативы в других СУБД
PostgreSQL/PostGIS: Функция ST_NumGeometries работает аналогично. Пример:
SELECT ST_NumGeometries(ST_GeomFromText('MULTIPOINT(0 0, 1 1, 2 2)'));3
MySQL: Функция ST_NumGeometries доступна с версии 5.6. Пример:
SELECT ST_NumGeometries(ST_GeomFromText('MultiPoint(1 1, 2 2, 3 3)'));3
Oracle Spatial: Используется функция SDO_UTIL.GETNUMELEM или атрибут SDO_ORDINATE_ARRAY. Пример отличается структурой:
SELECT SDO_UTIL.GETNUMELEM(SDO_GEOMETRY(2005, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,3), SDO_ORDINATE_ARRAY(1,1, 2,2, 3,3))) FROM DUAL;3
SQLite с SpatiaLite: Функция NumGeometries. Пример:
SELECT NumGeometries(GeomFromText('MULTIPOINT(0 0, 1 1)'));2
Типичные ошибки при использовании
Ошибка при вызове для неинициализированного объекта:
DECLARE @geom geometry;
SELECT @geom.STNumGeometries();NULL
Ошибочное ожидание возврата 0 для пустой коллекции. Фактически пустая коллекция возвращает 1:
DECLARE @empty geometry = geometry::Parse('GEOMETRYCOLLECTION EMPTY');
SELECT @empty.STNumGeometries();1
Путаница с индексацией. Метод STGeometryN использует 1-базовую индексацию, что может привести к ошибкам:
DECLARE @mp geometry = geometry::STGeomFromText('MULTIPOINT((1 1), (2 2))', 0);
SELECT @mp.STGeometryN(0).ToString(); -- Неверный индексNULL
Изменения в последних версиях
Функция STNumGeometries не претерпела значительных изменений в синтаксисе или поведении с момента первоначального внедрения в SQL Server 2008. Основные улучшения касались общей производительности пространственных запросов и оптимизации обработки геометрических данных.
В SQL Server 2012 и более поздних версиях были улучшены алгоритмы обработки мультигеометрических объектов, что может незначительно влиять на скорость выполнения STNumGeometries для сложных объектов.
В последних версиях SQL Server также расширена совместимость со стандартами OGC (Open Geospatial Consortium), но базовое поведение функции остается неизменным.
Расширенные примеры применения
Использование в запросе для фильтрации мультигеометрических объектов:
WITH SpatialData AS (
SELECT 1 AS id, geometry::STGeomFromText('MULTIPOINT((1 1), (2 2), (3 3))', 0) AS geom
UNION ALL
SELECT 2, geometry::STGeomFromText('POINT(4 4)', 0)
UNION ALL
SELECT 3, geometry::STGeomFromText('MULTIPOINT((5 5), (6 6))', 0)
)
SELECT id, geom.STNumGeometries() AS geom_count
FROM SpatialData
WHERE geom.STNumGeometries() > 1;id | geom_count ---|----------- 1 | 3 3 | 2
Анализ GeometryCollection с разными типами объектов:
DECLARE @complex geometry = geometry::STGeomFromText('GEOMETRYCOLLECTION(
POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)),
LINESTRING(0 0, 20 20),
POINT(5 5),
MULTIPOINT((1 1), (2 2))
)', 0);
SELECT
@complex.STNumGeometries() AS total_geometries,
@complex.STGeometryN(1).STGeometryType() AS geom1_type,
@complex.STGeometryN(4).STNumGeometries() AS multipoint_count;total_geometries | geom1_type | multipoint_count -----------------|------------|----------------- 4 | Polygon | 2
Построение динамического SQL на основе количества геометрий:
DECLARE @geom geometry = geometry::STGeomFromText('MULTIPOINT((1 1), (2 2), (3 3), (4 4))', 0);
DECLARE @count INT = @geom.STNumGeometries();
DECLARE @i INT = 1;
DECLARE @sql NVARCHAR(MAX) = 'SELECT ';
WHILE @i <= @count
BEGIN
SET @sql = @sql + 'geometry' + CAST(@i AS NVARCHAR) + ' = ''' +
@geom.STGeometryN(@i).ToString() + '''';
IF @i < @count SET @sql = @sql + ', ';
SET @i = @i + 1;
END
PRINT @sql;SELECT geometry1 = 'POINT (1 1)', geometry2 = 'POINT (2 2)', geometry3 = 'POINT (3 3)', geometry4 = 'POINT (4 4)'