我有一个postgres数据库,有几个表(几百个)。数据库中表的子集 Foo 具有相同的架构。
理想情况下,我想创建一个存储过程,该存储过程可以针对单个表运行查询,也可以针对子集 Foo 中的所有表运行。
伪代码:
from_date = Date.new(2016, 1, 1)
to_date = Date.today
Sidekiq.redis do |redis|
redis.del("stat:processed")
redis.del("stat:failed")
(from_date..to_date).each do |date|
redis.del("stat:processed:#{date}")
redis.del("stat:failed:#{date}")
end
end
我如何在Postgresql 9.x中实现此要求?
答案 0 :(得分:6)
你应该看一下PostgreSQL中的table inheritance,它们完全允许你说的话。
例如,您可以创建表parent_tbl:
CREATE TABLE parent_tbl (id INTEGER, name VARCHAR(32), weight numeric, age INTEGER);
然后将您的表链接到此父表:
ALTER TABLE tbl_a INHERIT parent_tbl;
ALTER TABLE tbl_b INHERIT parent_tbl;
ALTER TABLE tbl_c INHERIT parent_tbl;
ALTER TABLE tbl_d INHERIT parent_tbl;
然后,通过parent_tbl的SELECT查询将查询所有tbl_x表,而对tbl_x的查询将仅查询此特定表。
INSERT INTO tbl_a VALUES (1, 'coucou', 42, 42);
SELECT * FROM tbl_a;
id | name | weight | age
----+--------+--------+-----
1 | coucou | 42 | 42
(1 row)
SELECT * FROM parent_tbl;
id | name | weight | age
----+--------+--------+-----
1 | coucou | 42 | 42
(1 row)
SELECT * FROM tbl_b;
id | name | weight | age
----+--------+--------+-----
(0 rows)
也可以从给定的子表中过滤数据。例如,如果您对来自表tbl_a和tbl_b的数据感兴趣,可以这样做
select id, name, weight, age
from parent_tbl
left join pg_class on oid = parent_tbl.tableoid
where relname in ('tbl_a', 'tbl_b');
编辑:我把数字用于重量而不是双倍,因为我的服务器不支持此类型。
答案 1 :(得分:4)
要使用数组中的项(表名)动态创建选择查询,可以使用以下select语句
SELECT string_agg(q, ' union all ')
FROM (
SELECT 'select * from ' || unnest(array ['tble_a','tble_b']) AS q
) t
结果:
string_agg
---------------------------------------------------
select * from tble_a union all select * from tble_b
您可以创建返回带列
的表的函数 id INTEGER
,name VARCHAR(32)
,weight numeric
,age INTEGER
P.S:我在避免TYPE person_info
功能:
CREATE
OR REPLACE FUNCTION generic_func (tbl varchar [])
RETURNS TABLE ( -- To store the output
id INTEGER
,name VARCHAR(32)
,weight numeric
,age INTEGER
) AS $BODY$
DECLARE qry text;
BEGIN
SELECT string_agg(q, ' union all ') --To create select query dynamically
INTO qry
FROM (
SELECT 'select * from ' || unnest(tbl) AS q
) t;
RAISE NOTICE 'qry %',qry; --optional
RETURN query --Executes the query to the defined table
EXECUTE qry;
END;$BODY$
LANGUAGE plpgsql VOLATILE
用法:
select * from generic_func(array['tbl_a','tbl_b','tbl_c','tbl_d'])
结果:
id name weight age
-- ---- ------ ---
2 ABC 11 112
2 CBC 11 112
2 BBC 11 112
2 DBC 11 112
和
select * from generic_func(array['tbl_a'])
Result:
id name weight age
-- ---- ------ ---
2 ABC 11 112