ST_Collect() în MySQL

Operații spațiale MySQL 8.0+

Funcție de agregare: strânge geometriile din mai multe rânduri într-o singură geometrie Multi sau colecție.

Sintaxă
ST_Collect([DISTINCT] geometrie) [OVER (...)]

Ce face ST_Collect()

ST_Collect() (din MySQL 8.0.24) este pentru geometrii ce este GROUP_CONCAT() pentru texte. Rezultatul este cel mai precis tip posibil: doar puncte dau un MULTIPOINT, doar linii un MULTILINESTRING, doar poligoane un MULTIPOLYGON, iar tipurile amestecate o GEOMETRYCOLLECTION.

Valorile NULL sunt ignorate; dacă nu rămâne nimic, rezultatul este NULL. Cu DISTINCT, geometriile repetate apar o singură dată. Funcționează cu GROUP BY și ca funcție fereastră (OVER). Toate geometriile trebuie să aibă același SRID.

Parametri

Parametru Descriere
geometrie Coloana sau expresia spațială.
DISTINCT Opțional: elimină geometriile repetate.

Ce returnează

O geometrie Multi, o colecție sau NULL.

Exemple

Exemplele de pe această pagină pornesc de la datele de mai jos. Rulează mai întâi acest cod, apoi exemplul.

CREATE TABLE orase (
  id INT PRIMARY KEY,
  nume VARCHAR(20),
  loc POINT NOT NULL SRID 4326,
  SPATIAL INDEX (loc)
);

INSERT INTO orase VALUES
  (1, 'Iași',        ST_GeomFromText('POINT(47.1585 27.6014)', 4326)),
  (2, 'Cluj-Napoca', ST_GeomFromText('POINT(46.7712 23.6236)', 4326)),
  (3, 'București',   ST_GeomFromText('POINT(44.4268 26.1025)', 4326)),
  (4, 'Timișoara',   ST_GeomFromText('POINT(45.7489 21.2087)', 4326)),
  (5, 'Constanța',   ST_GeomFromText('POINT(44.1598 28.6348)', 4326));

CREATE TABLE cartiere (
  id INT PRIMARY KEY,
  nume VARCHAR(20),
  forma POLYGON NOT NULL
);

INSERT INTO cartiere VALUES
  (1, 'Centru',   ST_GeomFromText('POLYGON((0 0,4 0,4 4,0 4,0 0))')),
  (2, 'Copou',    ST_GeomFromText('POLYGON((0 4,4 4,4 8,0 8,0 4))')),
  (3, 'Tătărași', ST_GeomFromText('POLYGON((3 1,7 1,7 5,3 5,3 1))')),
  (4, 'Galata',   ST_GeomFromText('POLYGON((10 0,13 0,13 3,10 3,10 0))'));

CREATE TABLE magazine (
  id INT PRIMARY KEY,
  nume VARCHAR(20),
  loc POINT NOT NULL
);

INSERT INTO magazine VALUES
  (1, 'Librăria Ana',   Point(1, 1)),
  (2, 'Florăria Dan',   Point(2, 6)),
  (3, 'Brutăria Ioana', Point(5, 3)),
  (4, 'Cafeneaua Mara', Point(4, 2)),
  (5, 'Atelierul Radu', Point(12, 1));

Exemplul 1: Toate orașele într-un MULTIPOINT

SELECT ST_AsText(ST_Collect(loc)) AS orase,
       ST_GeometryType(ST_Collect(loc)) AS tip
FROM orase
WHERE id <= 3;

Rezultat

+-------------------------------------------------------------------+------------+
| orase                                                             | tip        |
+-------------------------------------------------------------------+------------+
| MULTIPOINT((47.1585 27.6014),(46.7712 23.6236),(44.4268 26.1025)) | MULTIPOINT |
+-------------------------------------------------------------------+------------+

Exemplul 2: Magazinele grupate pe cartiere

SELECT c.nume AS cartier, ST_AsText(ST_Collect(m.loc)) AS magazine
FROM cartiere c JOIN magazine m ON ST_Intersects(c.forma, m.loc)
GROUP BY c.id, c.nume
ORDER BY c.id;

Rezultat

+-------------+-------------------------+
| cartier     | magazine                |
+-------------+-------------------------+
| Centru      | MULTIPOINT((1 1),(4 2)) |
| Copou       | MULTIPOINT((2 6))       |
| Tătărași    | MULTIPOINT((5 3),(4 2)) |
| Galata      | MULTIPOINT((12 1))      |
+-------------+-------------------------+

Exemplul 3: DISTINCT și tipuri amestecate

CREATE TABLE livrari (zi INT, punct POINT);
INSERT INTO livrari VALUES (1, Point(1, 1)), (1, Point(1, 1)), (1, Point(5, 3)), (2, NULL);

SELECT zi, ST_AsText(ST_Collect(punct)) AS toate, ST_AsText(ST_Collect(DISTINCT punct)) AS distincte
FROM livrari
GROUP BY zi;

SELECT ST_AsText(ST_Collect(g)) AS amestec
FROM (SELECT Point(1, 1) AS g UNION ALL SELECT ST_GeomFromText('LINESTRING(0 0,2 2)')) AS t;

Rezultat

+------+-------------------------------+-------------------------+
| zi   | toate                         | distincte               |
+------+-------------------------------+-------------------------+
|    1 | MULTIPOINT((1 1),(1 1),(5 3)) | MULTIPOINT((1 1),(5 3)) |
|    2 | NULL                          | NULL                    |
+------+-------------------------------+-------------------------+
+----------------------------------------------------+
| amestec                                            |
+----------------------------------------------------+
| GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,2 2)) |
+----------------------------------------------------+

Greșeli frecvente

  • Aștepți ca ST_Collect() să unească poligoanele care se suprapun. Le pune doar laolaltă într-un MULTIPOLYGON; pentru unire folosește ST_Union().

Comenzi înrudite

  • GeomCollection(): Pune geometrii de orice tip (puncte, linii, poligoane) într-o colecție; fără argumente creează o geometrie goală.
  • MultiPoint(), MultiLineString(), MultiPolygon(): Grupează mai multe puncte, linii sau poligoane într-o singură geometrie de tip „Multi”.
  • ST_Union(): Unește două geometrii într-una singură (reuniunea mulțimilor de puncte).
  • GROUP_CONCAT(): Lipește valorile unui grup într-un singur text, de exemplu toate produsele unei comenzi.