我尝试创建一个函数,该函数将返回以下查询的内容,其中proto_location是text类型。不确定它是否重要,但我当前调用此查询的java代码只是将每条记录作为字符串读取。
SELECT DISTINCT tm.proto_location
FROM track_message tm
WHERE tm.workflow_analytic_instance_id = 204
AND EXISTS ( SELECT *
FROM track_message_to_track_mapping tm2tm
JOIN track t ON t.id = tm2tm.track_id
JOIN track_item ti ON t.id = ti.track_id
JOIN track_point tp ON ti.id = tp.track_item_id
WHERE tm.id =tm2tm.track_message_id
AND ti.item_time BETWEEN 1328816277089000 AND 1328816287089000
AND ST_Intersects
(tp.track_position
, ST_GeomFromText('POLYGON((-144 59, -41 46, -75 15, -127 25, -144 59))',4326)
)
)
;
这是我的功能
CREATE OR REPLACE Function getTrackMessages(workflow bigint, start_time bigint, end_time bigint) returns text[]
as $$
SELECT DISTINCT tm.proto_location
FROM track_message tm
WHERE tm.workflow_analytic_instance_id = $1AND EXISTS ( SELECT *
FROM track_message_to_track_mapping tm2tm
JOIN track t ON t.id = tm2tm.track_id
JOIN track_item ti ON t.id = ti.track_id
JOIN track_point tp ON ti.id = tp.track_item_id
WHERE tm.id =tm2tm.track_message_id
AND ti.item_time BETWEEN $2 AND $3 AND ST_Intersects
(tp.track_position
, ST_GeomFromText('POLYGON((-144 59, -41 46, -75 15, -127 25, -144 59))',4326)
)
)
;
$$ Language 'plpgsql';
我一直收到一条错误,指出“select”或其附近的语法错误及其引用行
SELECT DISTINCT tm.proto_location
答案 0 :(得分:3)
CREATE OR REPLACE FUNCTION get_track_messages(workflow bigint, start_time bigint, end_time bigint)
RETURNS SETOF text[] AS
$func$
SELECT DISTINCT tm.proto_location
FROM track_message tm
WHERE tm.workflow_analytic_instance_id = $1
AND EXISTS (
SELECT *
FROM track_message_to_track_mapping tm2tm
JOIN track t ON t.id = tm2tm.track_id
JOIN track_item ti ON t.id = ti.track_id
JOIN track_point tp ON ti.id = tp.track_item_id
WHERE tm.id = tm2tm.track_message_id
AND ti.item_time BETWEEN $2 AND $3
AND ST_Intersects (tp.track_position
, ST_GeomFromText('POLYGON((-144 59, -41 46, -75 15, -127 25, -144 59))',4326)
)
);
$func$ LANGUAGE sql;
最重要的是,它可以用作 sql 功能 对于PL / pgSQL函数,您需要更改:
CREATE OR REPLACE FUNCTION get_track_messages(workflow bigint
, start_time bigint
, end_time bigint)
RETURNS SETOF text[] AS
$func$
BEGIN
RETURN QUERY
SELECT DISTINCT ... ;
END
$func$ LANGUAGE plpqsql;
如果查询返回的行数超过1行,您还需要SETOF
(正如您自己想象的那样)。你需要调用函数:
SELECT * FROM get_track_messages( ... );
另请注明语言名称plpgsql
或sql
。它是一个标识符,而不是字符串。
More about returning from a function in the manual.
如果proto_location
是character type,您可以这样汇总:
SELECT array_agg(DISTINCT tm.proto_location) ...
(实际上,您可以将array_agg()
与任何标量类型一起使用,但上面的函数定义为返回text[]
,因此您必须将其他类型转换为文本my_odd_column::text
。)
或者对于排序数组:
SELECT array_agg(DISTINCT tm.proto_location ORDER BY proto_location) ...
或者,要获取排序列表(text
)而不是数组(text[]
):
SELECT string_agg(DISTINCT tm.proto_location ORDER BY proto_location, ', ') ...
更多信息:
How to use array_agg() for varchar[]
Alternatives to Array_Agg: PostgreSQL