过滤函数返回的数据

时间:2016-09-21 16:41:46

标签: postgresql postgis

我有一个非常简单的查询,看起来像这样:

SELECT (ST_DumpPoints(geom)).path as path FROM layer

它使用一些返回integer[]类型的库函数。结果表中的数据如下所示:

{1}
{1,2}
{1}

我尝试了很多方法来过滤这些数据 - 例如,获取包含{2}的所有行。但我失败了。唯一有效的查询是这一个:

SELECT path FROM (
    SELECT (ST_DumpPoints(geom)).path as path FROM layer_60_ 
) t WHERE path @> '{2}'::integer[]

但在这种情况下使用子查询看起来有点矫枉过正。有没有可能在没有子查询的情况下立即过滤它?我自己的尝试以失败告终:

SELECT (ST_DumpPoints(geom)).path as path FROM layer_60_ WHERE path ... # indeed, wrong

SELECT (ST_DumpPoints(geom)).path as path FROM layer_60_ HAVING path ... # wrong

SELECT * FROM layer_60_ WHERE (ST_DumpPoints(geom)).path ... # does not work

SELECT (ST_DumpPoints(geom)).path as path FROM layer_60_ GROUP BY path HAVING path ... # wrong!!! 

那么,这有什么问题,是否有比子查询更简单的解决方案?

1 个答案:

答案 0 :(得分:2)

使用子查询不应该对您有任何顾虑。计划员无论如何都会将子查询折叠成单个计划。如果使用子查询更容易构造,理解和维护查询,那么 - 无论如何 - 继续。没有性能损失(除非您使用optimization barriers)。

在你的情况下,函数ST_DumpPoints()是一个集合返回函数,所以你应该真的将它用作行源,然后在没有子查询的情况下做你想做的事情变得相当容易:

SELECT p.path
FROM layer_60_, ST_DumpPoints(geom) p(path, geom)
WHERE p.path @> '{2}'::integer[];

对前一个表中的每一行计算一次该函数,然后将这些行连接起来,就像指定了一个连接条件一样。之后,您可以参考函数输出的列。