在我的Postgres 9.6数据库中,我有以下自定义域和表定义:
create domain lowResData as
float[21];
create table myRawValues (
id text,
myData lowResData,
xAxis lowResData,
primary key(id)
);
以下功能可以为单个项目生成我想要的结果。
create function getData(_id 'text') returns float[] as $$
select myData
from myRawValues
where id = _id
$$ language sql;
create function getAxis(_id 'text') returns float[] as $$
select xAxis
from myRawValues
where id = _id
$$ language sql;
create function myPlotter(myarray float[], myData float[])
returns table (frequency float, amplitude float) as
$$
select *
from unnest(myarray, myData) as u;
$$ language sql;
select * from myPlotter(getAxis('123'), getData('123'));
我想对执行特定查询所产生的所有 id
做同样的事情并最终获得如下结果:
create or replace function allIdLowResData() returns setof float[] as
$body$
declare r text;
begin
for r in (select id from myRawValues where /*SOME CONDITION*/)
loop
return next myPlotter(getAxis(r), getData(r));
end loop;
return;
end
$body$
language plpgsql;
答案 0 :(得分:1)
使用LATERAL
联接将您的set-returns函数与查询的其余部分组合在一起。像:
CREATE OR REPLACE FUNCTION allIdLowResData()
RETURNS TABLE (frequency float, amplitude float, id text) AS
$func$
SELECT p.*, r.id
FROM myRawValues r
LEFT JOIN LATERAL myPlotter(r.xAxis, r.myData) p ON true
WHERE /*SOME CONDITION*/
$func$ LANGUAGE sql;
请参阅:
另外,函数(RETURNS
)的声明返回类型必须与实际返回的内容相匹配。
在这里使用更简单的SQL函数。您可以使用PL / pgSQL执行相同的操作,在这种情况下使用RETURNS QUERY
。
您可能对Postgres数组定义的详细信息quoted from the manual:
感兴趣但是,当前实现会忽略任何提供的数组大小 限制,即行为与未指定的数组相同 长度。
当前实现不强制声明的数量 尺寸要么。特定元素类型的数组都是 被认为属于同一类型,无论大小或数量 尺寸。因此,声明数组的大小或维数
CREATE TABLE
只是文档;它不会影响运行时行为。
意思是,您的domain
目前是噪音而没有任何影响(除了并发症)。要在表中实际使用21个元素强制执行1维数组,请使用CHECK
约束。像:
CREATE DOMAIN lowResData AS float[21] -- "[21]" is just for documentation
CONSTRAINT dim1_elem21 CHECK (array_ndims(VALUE) = 1 AND array_length(VALUE, 1) = 21);
我还会抛弃函数getData()
和getAxis()
,除非它们有更多功能。