2

我有一個返回表的函數,它將多個調用的輸出累加到另一個返回表的函數中。我想在返回結果之前對構建的表執行最終查詢。目前,我實現了這個爲兩個功能,一個積累和一個進行最後的查詢,這是醜陋:合併多個結果表並對結果執行最終查詢

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; 

這怎麼能在單一功能做,優雅?

+1

記住,總是提供你的Postgres的版本和必要的範圍內 - 至少確切的結果類型'get_available_networks_gw(..)' –

回答

1

兩個函數簡化和合並,在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, $1) f(networkid, ct) 
     WHERE g.location_id = $2 
     GROUP BY 1' 
    , _schema_customer) 
    USING _schema_customer, _location_id; 
END 
$func$ LANGUAGE plpgsql; 

呼叫:

SELECT * FROM func_accu(123, 'my_schema'); 

相關:

我爲函數返回的列使用別名(f(networkid, ct)),因爲您沒有公開返回類型get_available_networks_gw()。您可以直接使用返回類型的列名稱。

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 = $2 
GROUP BY 1; 
+0

謝謝你,你的解決方案是完美的,很好的解釋! – Miha