# 12.17.12 空间聚合函数

MySQL 支持对一组值执行计算的聚合函数。有关这些功能的一般信息,请参阅第 12.20.1 节,“聚合函数描述”.本节介绍ST_Collect()空间聚合函数。

ST_Collect()可以用作窗口函数,正如其语法描述中所表示的那样[*over_clause*],代表一个可选的超过条款。*over_clause*描述在第 12.21.2 节,“窗口函数概念和语法”,其中还包括有关窗口函数使用的其他信息。

  • ST_Collect([DISTINCT] *g*) [*over_clause*]

    聚合几何值并返回单个几何集合值。随着清楚的选项,返回不同几何参数的聚合。

    与其他聚合函数一样,通过...分组可用于将参数分组为子集。ST_Collect()返回每个子集的聚合值。

    此函数作为窗口函数执行,如果*over_clause存在。over_clause如中所述第 12.21.2 节,“窗口函数概念和语法”.与大多数支持窗口化的聚合函数相比,ST_Collect()允许使用over_clause*和...一起清楚的.

    ST_Collect()处理其参数如下:

    • 空值参数被忽略。

    • 如果所有参数都是空值或者聚合结果为空,返回值为空值.

    • 如果任何几何参数不是语法上格式良好的几何,则ER_GIS_INVALID_DATA (opens new window)发生错误。

    • 如果任何几何参数是未定义的空间参考系统 (SRS) 中的语法结构良好的几何,则ER_SRS_NOT_FOUND (opens new window)发生错误。

    • 如果有多个几何参数并且这些参数在同一个 SRS 中,则返回值在该 SRS 中。如果这些参数不在同一个 SRS 中,则ER_GIS_DIFFERENT_SRIDS_AGGREGATION (opens new window)发生错误。

    • 结果是最窄的多*Xxx*要么几何集合值可能,结果类型由非空值几何参数如下:

      • 如果所有参数都是观点值,结果是多点价值。

      • 如果所有参数都是线串值,结果是多行字符串价值。

      • 如果所有参数都是多边形值,结果是多多边形价值。

      • 否则,参数是几何类型的混合,结果是几何集合价值。

      此示例数据集按年份和制造地点显示假设产品:

    CREATE TABLE product (
      year INTEGER,
      product VARCHAR(256),
      location Geometry
    );
    
    INSERT INTO product
    (year,  product,     location) VALUES
    (2000, "Calculator", ST_GeomFromText('point(60 -24)',4326)),
    (2000, "Computer"  , ST_GeomFromText('point(28 -77)',4326)),
    (2000, "Abacus"    , ST_GeomFromText('point(28 -77)',4326)),
    (2000, "TV"        , ST_GeomFromText('point(38  60)',4326)),
    (2001, "Calculator", ST_GeomFromText('point(60 -24)',4326)),
    (2001, "Computer"  , ST_GeomFromText('point(28 -77)',4326));
    

    一些示例查询使用ST_Collect()在数据集上:

    mysql> SELECT ST_AsText(ST_Collect(location)) AS result
           FROM product;
    +------------------------------------------------------------------+
    | result                                                           |
    +------------------------------------------------------------------+
    | MULTIPOINT((60 -24),(28 -77),(28 -77),(38 60),(60 -24),(28 -77)) |
    +------------------------------------------------------------------+
    
    mysql> SELECT ST_AsText(ST_Collect(DISTINCT location)) AS result
           FROM product;
    +---------------------------------------+
    | result                                |
    +---------------------------------------+
    | MULTIPOINT((60 -24),(28 -77),(38 60)) |
    +---------------------------------------+
    
    mysql> SELECT year, ST_AsText(ST_Collect(location)) AS result
           FROM product GROUP BY year;
    +------+------------------------------------------------+
    | year | result                                         |
    +------+------------------------------------------------+
    | 2000 | MULTIPOINT((60 -24),(28 -77),(28 -77),(38 60)) |
    | 2001 | MULTIPOINT((60 -24),(28 -77))                  |
    +------+------------------------------------------------+
    
    mysql> SELECT year, ST_AsText(ST_Collect(DISTINCT location)) AS result
           FROM product GROUP BY year;
    +------+---------------------------------------+
    | year | result                                |
    +------+---------------------------------------+
    | 2000 | MULTIPOINT((60 -24),(28 -77),(38 60)) |
    | 2001 | MULTIPOINT((60 -24),(28 -77))         |
    +------+---------------------------------------+
    
    # selects nothing
    mysql> SELECT ST_Collect(location) AS result
           FROM product WHERE year = 1999;
    +--------+
    | result |
    +--------+
    | NULL   |
    +--------+
    
    mysql> SELECT ST_AsText(ST_Collect(location)
             OVER (ORDER BY year, product ROWS BETWEEN 1 PRECEDING AND CURRENT ROW))
             AS result
           FROM product;
    +-------------------------------+
    | result                        |
    +-------------------------------+
    | MULTIPOINT((28 -77))          |
    | MULTIPOINT((28 -77),(60 -24)) |
    | MULTIPOINT((60 -24),(28 -77)) |
    | MULTIPOINT((28 -77),(38 60))  |
    | MULTIPOINT((38 60),(60 -24))  |
    | MULTIPOINT((60 -24),(28 -77)) |
    +-------------------------------+
    

    此功能是在 MySQL 8.0.24 中添加的。