合并多个结果表并对结果进行最终查询
Merge multiple result tables and perform final query on result
我有一个返回 table 的函数,它累积了对另一个返回 table 的函数的多次调用的输出。我想在返回结果之前对构建的 table 执行最终查询。目前我将其实现为 两个函数,一个累积和一个执行最终查询,这是丑陋的:
CREATE OR REPLACE FUNCTION func_accu(LOCATION_ID INTEGER, SCHEMA_CUSTOMER TEXT)
RETURNS TABLE("networkid" integer, "count" bigint) AS $$
DECLARE
GATEWAY_ID integer;
BEGIN
FOR GATEWAY_ID IN
execute format(
'SELECT id FROM %1$I.gateway WHERE location_id=%2$L'
, SCHEMA_CUSTOMER, LOCATION_ID)
LOOP
RETURN QUERY execute format(
'SELECT * FROM get_available_networks_gw(%1$L, %2$L)'
, GATEWAY_ID, SCHEMA_CUSTOMER);
END LOOP;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION func_query(LOCATION_ID INTEGER, SCHEMA_CUSTOMER TEXT)
RETURNS TABLE("networkid" integer, "count" bigint) AS $$
DECLARE
BEGIN
RETURN QUERY execute format('
SELECT networkid, max(count) FROM func_accu(%2$L, %1$L) GROUP BY networkid;'
, SCHEMA_CUSTOMER, LOCATION_ID);
END;
$$ LANGUAGE plpgsql;
如何在单函数中优雅地完成?
两个函数都经过简化和合并,还在 USING
clause:
中提供 value 参数
CREATE OR REPLACE FUNCTION pg_temp.func_accu(_location_id integer, schema_customer text)
RETURNS TABLE(networkid integer, count bigint) AS
$func$
BEGIN
RETURN QUERY EXECUTE format('
SELECT f.networkid, max(f.ct)
FROM %I.gateway g
, get_available_networks_gw(g.id, ) f(networkid, ct)
WHERE g.location_id =
GROUP BY 1'
, _schema_customer)
USING _schema_customer, _location_id;
END
$func$ LANGUAGE plpgsql;
通话:
SELECT * FROM func_accu(123, 'my_schema');
相关:
我正在为由函数 (f(networkid, ct)
) 编辑的 return 列使用别名来确定,因为您没有透露 get_available_networks_gw()
的 return 类型.可以直接使用return类型的列名。
FROM
子句中的逗号 (,
) 是 CROSS JOIN LATERAL ...
的缩写语法。需要 Postgres 9.3 或更高版本.
或者您可以 运行 这个查询而不是函数:
SELECT f.networkid, max(f.ct)
FROM myschema.gateway g, get_available_networks_gw(g.id, 'my_schema') f(networkid, ct)
WHERE g.location_id =
GROUP BY 1;
我有一个返回 table 的函数,它累积了对另一个返回 table 的函数的多次调用的输出。我想在返回结果之前对构建的 table 执行最终查询。目前我将其实现为 两个函数,一个累积和一个执行最终查询,这是丑陋的:
CREATE OR REPLACE FUNCTION func_accu(LOCATION_ID INTEGER, SCHEMA_CUSTOMER TEXT)
RETURNS TABLE("networkid" integer, "count" bigint) AS $$
DECLARE
GATEWAY_ID integer;
BEGIN
FOR GATEWAY_ID IN
execute format(
'SELECT id FROM %1$I.gateway WHERE location_id=%2$L'
, SCHEMA_CUSTOMER, LOCATION_ID)
LOOP
RETURN QUERY execute format(
'SELECT * FROM get_available_networks_gw(%1$L, %2$L)'
, GATEWAY_ID, SCHEMA_CUSTOMER);
END LOOP;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION func_query(LOCATION_ID INTEGER, SCHEMA_CUSTOMER TEXT)
RETURNS TABLE("networkid" integer, "count" bigint) AS $$
DECLARE
BEGIN
RETURN QUERY execute format('
SELECT networkid, max(count) FROM func_accu(%2$L, %1$L) GROUP BY networkid;'
, SCHEMA_CUSTOMER, LOCATION_ID);
END;
$$ LANGUAGE plpgsql;
如何在单函数中优雅地完成?
两个函数都经过简化和合并,还在 USING
clause:
CREATE OR REPLACE FUNCTION pg_temp.func_accu(_location_id integer, schema_customer text)
RETURNS TABLE(networkid integer, count bigint) AS
$func$
BEGIN
RETURN QUERY EXECUTE format('
SELECT f.networkid, max(f.ct)
FROM %I.gateway g
, get_available_networks_gw(g.id, ) f(networkid, ct)
WHERE g.location_id =
GROUP BY 1'
, _schema_customer)
USING _schema_customer, _location_id;
END
$func$ LANGUAGE plpgsql;
通话:
SELECT * FROM func_accu(123, 'my_schema');
相关:
我正在为由函数 (f(networkid, ct)
) 编辑的 return 列使用别名来确定,因为您没有透露 get_available_networks_gw()
的 return 类型.可以直接使用return类型的列名。
FROM
子句中的逗号 (,
) 是 CROSS JOIN LATERAL ...
的缩写语法。需要 Postgres 9.3 或更高版本.
或者您可以 运行 这个查询而不是函数:
SELECT f.networkid, max(f.ct)
FROM myschema.gateway g, get_available_networks_gw(g.id, 'my_schema') f(networkid, ct)
WHERE g.location_id =
GROUP BY 1;