我有以下程序:
CREATE OR REPLACE FUNCTION findKNN()
RETURNS Text AS $body$
DECLARE
cur refcursor;
tempcur refcursor;
gid_ integer;
_var1 integer;
_var2 integer;
BEGIN
open cur for execute('select gid from polygons');
loop
fetch cur into gid_;
open tempcur for SELECT g1.gid , g2.gid FROM polygons AS g1, polygons AS g2
WHERE g1.gid = gid_ and g1.gid <> g2.gid ORDER BY g1.gid , ST_Distance(g1.the_geom,g2.the_geom)
LIMIT 5;
loop
fetch tempcur into _var1 , _var2;
-- how to return _var1 , _var2 here ?
end loop;
end loop;
close cur;
END;
$body$
LANGUAGE plpgsql;
但我不知道如何从这个程序中返回结果。对于外部游标循环中的每次执行,查询返回5行。如何为每个查询执行检索这五行?
答案 0 :(得分:3)
除非您尝试做一些不在您问题中的更复杂的事情,否则您可以从根本上简化为:
CREATE OR REPLACE FUNCTION find_knn()
RETURNS TABLE(gid1 integer, gid2 integer) AS
$body$
BEGIN
RETURN QUERY
SELECT g1.gid , g2.gid
FROM polygons g1
JOIN polygons g2 ON g1.gid <> g2.gid
-- WHERE g1.gid = <some_condition> -- ???
ORDER BY g1.gid, st_distance(g1.the_geom, g2.the_geom)
LIMIT 5;
END;
$body$ LANGUAGE plpgsql;
甚至:
CREATE OR REPLACE FUNCTION find_knn()
RETURNS TABLE(gid1 integer, gid2 integer) AS
$body$
SELECT g1.gid , g2.gid
FROM polygons g1
JOIN polygons g2 ON g1.gid <> g2.gid
-- WHERE g1.gid = <some_condition> -- ???
ORDER BY g1.gid, st_distance(g1.the_geom, g2.the_geom)
LIMIT 5;
$body$ LANGUAGE sql;
呼叫:
SELECT * FROM x.find_knn();
关于Returning From a Function的手册 有关CREATE FUNCTION。
的手册(回答评论。)
有很多方法可以在不实际评估整个连接的情况下选择一小部分巨大连接。在大多数情况下,您甚至不必担心它。例如,在家里运行:
EXPLAIN ANALYZE
SELECT *
FROM huge_tbl t1
CROSS JOIN huge_tbl t2
LIMIT 5
您将看到只处理5行,不整个交叉联接 CTE:
也是如此WITH a AS (
SELECT *
FROM huge_tbl t1
CROSS JOIN huge_tbl t2
)
SELECT *
FROM a
LIMIT 5
有一些限制。我引用excellent manual:
PostgreSQL的实现仅评估WITH的多行 查询是父查询实际获取的。
为了绝对确定,您可以在源头应用LIMIT
(或拟合WHERE
子句):
SELECT *
FROM (SELECT * FROM huge_table LIMIT 1) t1
CROSS JOIN (SELECT * FROM huge_table LIMIT 5) t2;