编辑
是的,你是对的。我在伪代码中寻找的是
列表(st_area(geom)> 0.1)或(COUNT(*)> 1)
用文字表示:
返回一个列表,该列表仅包含面积大于0.1的状态,但如果该州是该国家中唯一的州,则不排除该状态(通常和岛国,其旁边有足够的标签空间)它)。被排除在外的州是像斯洛文尼亚这样拥有100个省份的地方,但土地面积很小(英国也是罪犯)。
我有一张表,列出了所有州和省的整个世界(我称之为表状态,但它也可以指省)。
StateName,ContryName,Pop,geometry
该表位于PostGreSQL 9.2 PostGIS 2.0
上我需要移除小状态(区域太小)来标记。但如果它是一个岛屿(一个国家,一个州),那么我想留下它。
我的Naive查询是这样的,但是存在语法错误:
SELECT s.name,s.admin, st_area(geom)
FROM vector.states s
INNER JOIN (
SELECT ss.admin
FROM vector.states ss
GROUP BY ss.admin
HAVING (COUNT(*) > 1) AND (st_area(ss.geom) > 0.01)
) a ON a.admin = s.admin
ORDER BY s.admin ASC;
这是语法错误(我预计会发生这种情况)。
ERROR: column "ss.geom" must appear in the GROUP BY clause or be used in an aggregate function
LINE 7: HAVING (COUNT(*) > 1) AND (st_area(ss.geom) > 0.01)
答案 0 :(得分:1)
两个问题:
GROUP BY
中没有列出geom,则需要将其包装在聚合函数中。你可以使用min()
... COUNT(*) = 1 OR ..
但使用NOT EXISTS
进行反半连接可以更优雅地解决这个问题:
SELECT s.name, s.admin, st_area(geom)
FROM vector.states s
WHERE st_area(s.geom) > 0.01 -- state big enough ...
OR NOT EXISTS ( -- ... or there are no other counties
SELECT 1 FROM vector.states s2
WHERE s2.admin = s.admin
AND s2.pk_column <> s.pk_column -- exclude self-join
)
ORDER BY s.admin;
将pk_column
替换为您的实际主键列。
答案 1 :(得分:0)
编辑答案,第一次抱歉,我没有理解这个问题
试试这个:
SELECT s.name,s.admin, st_area(geom)
FROM vector.states s
WHERE s.admin in (
SELECT ss.admin
FROM vector.states ss
GROUP BY ss.admin
HAVING (COUNT(*) > 1)
)
AND (st_area(s.geom) > 0.01)
ORDER BY s.admin ASC;
希望它有所帮助!
答案 2 :(得分:0)
此部分:(st_area(ss.geom) > 0.01)
不属于HAVING
子句。 HAVING
是基于汇总函数限制结果,例如COUNT
,但对于其他函数,您必须使用WHERE
。
然后,我将使用两个单独的查询来获取这些不同的值:
SELECT s.NAME, s.admin, st_area(geom)
FROM vector.states s
INNER JOIN (
(SELECT ss.admin
FROM vector.states ss
WHERE st_area(ss.geom) > 0.01
GROUP BY ss.admin
HAVING COUNT(ss.admin) > 1)
UNION ALL
(SELECT ss.admin
FROM vector.states ss
GROUP BY ss.admin
HAVING COUNT(ss.admin) = 1)
) a
ON a.admin = s.admin
ORDER BY s.admin ASC;