SQLite:为每组实体检索单个代表实体

时间:2012-03-19 17:06:08

标签: sql sqlite

如果我有一个包含指定城市加油站的表格,每个加油站的名称和纬度+经度:

city        | name         | latitude      | longitude
---------------------------------------------------------
Berlin      | GasPump1     | 52.5          | 13.5
Berlin      | GasPump2     | 52.52         | 13.51
Zagreb      | INA1         | 45.8          | 16
Zagreb      | INA2         | 45.81         | 16.01
Zagreb      | INA3         | 45.82         | 15.99

如何使用单个SQL查询获取每个城市的单个代表实体?也就是说,我将如何使用单个查询来实现以下伪代码:

representativeStationsArray = []
citiesArray = sqlQuery("SELECT DISTINCT city FROM gasstations")
for city in citiesArray:
    representativeStation = sqlQuery(
        "SELECT * FROM gasstations WHERE city = ? LIMIT 1;", 
        city)
    representativeStationsArray.append(representativeStation)

我已经接受了答案,但我认为解释我对未来读者的需求可能会很有趣。

在iOS上,一旦用户缩小,地图视图上显示的注释太多会降低应用程序的速度。我正在尝试的第一个实验性解决方案(对于我正在开发的国家应该没问题)是按城市过滤注释,并为每个城市显示随机注释。

如果这不能令人满意,我会寻找另一种解决方案。

1 个答案:

答案 0 :(得分:2)

如果通过“代表行”,您只是指“城市匹配的任意行”,那么您可以使用GROUP BY:

SELECT * FROM gasstations
GROUP BY city

city以外的字段将填充来自任意组匹配行的数据。

来自http://sqlite.org/lang_select.html#resultset (强调我的)的文档:

  

如果SELECT语句是带有GROUP BY子句的聚合查询...

     

然后对每个表达式评估结果集中的每个表达式   一排排。如果表达式是聚合表达式,则为   在组中的所有行上进行评估。 否则,将对其进行评估   针对组内任意选择的一行。如果   结果集中有多个非聚合表达式,   然后对同一行评估所有这些表达式。

注意:它适用于SQLite和MySQL以及其他一些数据库。但是,许多(大多数?)数据库不允许您在分组查询中选择非聚合字段。因此,如果您曾经切换过数据库或部署到不同的生产数据库,请注意这一点。