1

在我的 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'));

结果1

我想对执行特定查询产生的所有 id' 执行相同的操作,并最终得到如下结果:

reslt2

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;
4

1 回答 1

2

使用LATERAL连接将您的集合返回函数与查询的其余部分结合起来。像:

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 函数。RETURNS QUERY你可以对 PL/pgSQL 做同样的事情,在这种情况下是领先的。

您可能对手册中引用的有关 Postgres 数组定义的这些详细信息感兴趣:

但是,当前实现忽略了任何提供的数组大小限制,即行为与未指定长度的数组相同。

当前的实现也不强制声明的维数。无论大小或维数如何,特定元素类型的数组都被认为是同一类型。因此,在其中声明数组大小或维数 CREATE TABLE只是文档;它不会影响运行时行为。

意思是,您domain目前是没有任何影响的噪音(除了并发症)。要实际执行表中恰好包含 21 个元素的一维数组,请使用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()除非它们有更多功能。

于 2017-12-13T17:00:50.027 回答