Search code examples
mysqlsqlgeospatialspatialspatial-query

Fetching Multipoint Spatial Data in MySQL


I didn't find any answer how to select every point in multipoint data type in MySQL. I have multipoint that contains many points and I want to select every point by query and I can't figure it out. Any ideas?

Table structure: Image

Example data: Image

In MySQL documentation I've found only this, but it didn't help: https://dev.mysql.com/doc/refman/8.0/en/fetching-spatial-data.html


Solution

  • If you are using MySQL >= 8.0.2, an option may be:

    DELIMITER //
    
    CREATE PROCEDURE `sp_test`(`p_id` BIGINT UNSIGNED)
    BEGIN
      SET @`sql` := CONCAT('
        WITH RECURSIVE `sequence` AS (
          SELECT 1 `seq`
          UNION ALL
          SELECT `seq` + 1 `seq`
          FROM `sequence`
          WHERE `sequence`.`seq` < ?
        )
        SELECT
          `sequence`.`seq` `id`,
          ST_AsText(ST_GeometryN(`points`, `sequence`.`seq`)) `point`
        FROM `sequence`
          INNER JOIN `tb_test` ON
            `tb_test`.`id` = ', `p_id`);
    
      SET @`limit` := (
        SELECT
          ST_NumGeometries(`points`)
        FROM
          `tb_test`
        WHERE
          `id` = `p_id`
      );
    
      PREPARE `stmt` FROM @`sql`;
      EXECUTE `stmt` USING @`limit`;
      DEALLOCATE PREPARE `stmt`;
    END//
    
    DELIMITER ;
    

    See db-fiddle.

    UPDATE

    DELIMITER //
    
    CREATE PROCEDURE `sp_test`(`p_id` BIGINT UNSIGNED)
    BEGIN
      SET @`sql` := CONCAT('
        WITH RECURSIVE `sequence` AS (
          SELECT 1 `seq`
          UNION ALL
          SELECT `seq` + 1 `seq`
          FROM `sequence`
          WHERE `sequence`.`seq` < ?
        )
        SELECT
          `sequence`.`seq` `id`,
          ST_AsText(ST_GeometryN(`points`, `sequence`.`seq`)) `point`,
          ST_X(ST_GeometryN(`points`, `sequence`.`seq`)) `X`,
          ST_Y(ST_GeometryN(`points`, `sequence`.`seq`)) `Y`
        FROM `sequence`
          INNER JOIN `tb_test` ON
            `tb_test`.`id` = ', `p_id`);
    
      SET @`limit` := (
        SELECT
          ST_NumGeometries(`points`)
        FROM
          `tb_test`
        WHERE
          `id` = `p_id`
      );
    
      PREPARE `stmt` FROM @`sql`;
      EXECUTE `stmt` USING @`limit`;
      DEALLOCATE PREPARE `stmt`;
    END//
    
    DELIMITER ;
    

    See db-fiddle.