在现有视图的基础上合并视图/添加条件

时间:2014-04-21 21:39:34

标签: postgresql view filter criteria

我有一个存储在架构view中的顶级schem1,它从某个表中驱动它的数据,掩盖了不相关的数据。 应用程序会对数据发出多个不同的标准,以便出于其他原因屏蔽其他行。

数据处理使用存储过程完成。我希望应用程序能够以一种应用程序可以“按需”添加“过滤器”的方式将它想要的任何过滤器(或者不是)发回到TEMPORARY视图,换句话说,我正在寻找对于一种存储临时视图的方法,它可以驱动新视图所在的临时视图中的数据。

对我想要实现的目标的另一种解释是在现有视图的基础上组合新标准的方法,以便对该视图的参考将使用“基本视图+新标准”

据我所知,pgsql不会“编译”视图,而是将其用作SQL文本,因此引用相同的view被视为递归调用(当实际上我想要做的是引用FROM子句中的“前一层视图”。

3 个答案:

答案 0 :(得分:1)

听起来你实际上正在寻找一张临时表,例如:

create temporary table current_data as
select * from filtered_view;

http://www.postgresql.org/docs/current/static/sql-createtableas.html

如果额外的行不在那里,则根据需要通过简单的插入来跟随它,如果不是,则按照反连接:

insert into current_data
select * from other_view
left join current_data using (whatever_pkey)
where current_data is null;

完成临时表填写后,运行analyze current_data并创建适用的索引(如果它包含足够的数据),然后继续在查询中使用它,就像您通常那样。

答案 1 :(得分:1)

postgres中的视图不是动态过滤数据的最佳工具。 每次定义新过滤器时创建新视图都在寻找麻烦(不提及性能成本)。

要在我的应用程序中生成报告,我使用返回查询的函数。 这些函数将过滤器值作为参数。 您可以将它们视为参数化视图

为了满足您的条件,我提出以下解决方案。 当然,它只是一个大纲。

我们说客户是您的顶级视图,它包含字段名称

创建一个表格,我们将在其中存储编号过滤器:

create table filters (
    id serial primary key,
    filter text);

要定义新过滤器,只需将其插入表中即可:

insert into filters (filter)
values ('name like ''%John%''');

将我们的参数化视图定义为一个函数,该函数根据过滤器中的值过滤来自客户的数据:

create or replace function show_customers()
    returns setof customers
    language plpgsql
as $$
declare
    _filter text;
    _query text = 'select * from customers where true ';
begin
    for _filter in 
        select filter from filters order by id
    loop
        _query = _query || ' and (' || _filter || ')';
    end loop;
    return query execute _query;
end $$;

现在,如果您调用该功能,您将根据过滤器表的当前状态获取过滤后的数据。

select * from show_customers();

请注意,您可以完全控制当前过滤器。您可以通过清空表格过滤器来重置它们,您可以删除一个或多个等等。

答案 2 :(得分:0)

一个选项(如果你有另一个想法请回答)是从视图的模式定义中提取查询,并将其指定为新过滤器的表以从中拉出它。

即。如果视图是

select * from users;

然后我们删除旧视图并使用新标准创建一个新视图使用现有视图 然后,新视图将由

之类的查询组成
select * FROM ( select * from users ) as t where user_id>100

通过这种方式,可以以类似的方式将额外的过滤器相互添加在一起。