我正试图在几张桌子上获取大量功能,而且我的目前是pSQL容量。使用9.6.2。
我正在尝试以可变数量的日期时间收集所有这些功能。目前,我在一个时间戳上运行它,并且不得不一遍又一遍地调用它,这对我来说太慢了。
我想发送一个在FROM(... UNION ...)中使用的时间戳数组。
CREATE OR REPLACE FUNCTION features_at_times(timestamp[])
RETURNS TABLE (
str_street_id varchar,
....blahhh, blah, blah.......
Zone integer,
DateTime timestamp
) AS
$func$
DECLARE
stamp timestamp[];
stamps timestamp[]:= array[];
BEGIN
RETURN QUERY
FOREACH stamp SLICE 1 IN ARRAY $1
LOOP
SELECT
str_stuff_id,
.....blahhh, blah, blah....
COALESCE(MAX(zone_id), 0) "Zone",
MAX("DateTime") "DateTime"
FROM (
SELECT
thingo.*,
str_timezone,
timestamp stamp AT TIME ZONE str_timezone "DateTime"
FROM thingo
JOIN destination ON pk_city = pk_destination
WHERE pk_city = '8fzdd56-7a52-11df-a34f-6b84rw853d3d'
AND thingo.pk_thingo_status = 2
UNION
SELECT
alt_thingo.*,
str_timezone,
timestamp stamp AT TIME ZONE str_timezone "DateTime"
FROM thingo
JOIN thingo AS alt_thingo USING (str_stuff_id)
JOIN destination ON thingo.pk_city = pk_destination
WHERE thingo.pk_city = '8fzdd56-7a52-11df-a34f-6b84rw853d3d'
AND thingo.pk_thingo_status = 2
) as base
LEFT JOIN block_observation_by_bin
ON thingo_observation_by_bin.thingo_id = pk_thingo_id
AND thingo_observation_by_bin.bin_id = ((to_char("DateTime",'D')::int - 1) * 24 + to_char("DateTime", 'HH24')::int)
AND thingo_observation_by_bin.market_id = 94
LEFT JOIN block_observation
ON thingo_observation.thingo_id = pk_thingo_id
AND thingo_observation.market_id = 94
WHERE base.pk_thingo = '027ecb54-51ec-41a6-a57e-666fddbbff35'
GROUP BY str_stuff_id;
END LOOP;
END;
$func$ LANGUAGE plpgsql;
我需要n次同样的读数。我看到FOREACH是一个选项,但我一直得到的只是错误。我想将时间戳传递给内部的两个SELECTS。
另外,我是否必须使用函数在psql中使用FOREACH?
答案 0 :(得分:1)
RETURN QUERY
的参数必须是SQL语句,但FOREACH
是PL / pgSQL而不是SQL。
此外,
timestamp stamp AT TIME ZONE str_timezone "DateTime"
是无效的SQL。我没有检查是否有其他错误。
要从一个PL / pgSQL函数中的多个表中返回行,您必须使用这样的游标循环:
DECLARE
ats timestamp without time zone;
arow record;
BEGIN
/* loop through the timestamps in the argument array */
FOREACH ats IN ARRAY $1 LOOP
/* loop through the results of the first query */
FOR arow IN
SELECT ...
LOOP
RETURN NEXT ...;
END LOOP;
/* loop through the results of the second query */
FOR arow IN
SELECT ...
LOOP
RETURN NEXT ...;
END LOOP;
...
END LOOP;
END;