我需要在几个表上执行相同的操作。现在查询看起来像这样:
create view foobar
as
select this, that
from here
where this=1
union all
select this,that
from there
where this=1
..... .....
等等,对于几个表。所有结果都是联合的。
有没有办法,而不是写这个很长的查询很容易出错,写一些像
for table in here, there, upthere
do
select this, that from $table where this=1
然后将它们联合起来。
我现在有查询工作,这需要一段时间,但这只是好奇心,我不知道如何在Google上搜索这个!
答案 0 :(得分:4)
从您需要的所有表格VIEW
中创建UNION
,然后SELECT
从VIEW
创建VIEW
。
此外,您可以像这样创建CREATE OR REPLACE VIEW table_set AS
SELECT 'table1' as table_name, field1, field2 ...
FROM table1
UNION ALL
SELECT 'table2' as table_name, field1, field2 ...
FROM table2
UNION ALL
SELECT 'table3' as table_name, field1, field2 ...
FROM table3
UNION ALL
...
:
SELECT
来自此VIEW
的和SELECT field1, field3
FROM table_set
WHERE table_name IN ('table2','table4')
AND field5 = 'abc'
赞:
{{1}}
答案 1 :(得分:1)
视图 like @Igor desrcibes是一种选择。
如果性能至关重要并且您没有大量的写入操作,则可以使用该视图(重新)创建materialized view。
或者,对于源表的较短语法和动态选择,您可以使用像这样的 plpgsql函数:
CREATE OR REPLACE FUNCTION f_select_from_tbls(tables text[], cond int)
RETURNS TABLE (this int, that text) AS
$BODY$
DECLARE
tbl text; -- automatically avoids SQLi
BEGIN
FOREACH tbl IN ARRAY tables LOOP
RETURN QUERY EXECUTE format('
SELECT this, that
FROM %I
WHERE this = $1', tbl)
USING cond;
END LOOP;
END
$BODY$
LANGUAGE plpgsql;
呼叫:
SELECT * FROM f_select_from_tbls('{t1,t2,nonStandard tablename}', 4);
我假设有许多表共享相同名称和类型(this int, that text)
的列(您没有在问题中定义数据类型。)该函数将array of text
作为表名称和integer
值为条件。
有关手册中Looping Through Arrays的更多信息 有关Returning From a Function的更多信息,请参阅手册。
使用动态SQL,您必须警惕 SQL注入。这种威胁在两方面得到了中和:
tables
中的表名称使用函数format()
注入,该函数正确引用任何非标准表名称cond
中的值通过USING
传递,从而使SQLi无法实现。VARIADIC
parameter 目的是使函数调用更简单。您可以提交文本变量列表,而不是从中构建数组(数组是从参数内部构建的)。就是这样。
CREATE OR REPLACE FUNCTION f_select_from_tbls2(cond int, VARIADIC tables text[])
RETURNS TABLE (this int, that text) AS
$BODY$
DECLARE
tbl text; -- automatically avoids SQLi
BEGIN
FOREACH tbl IN ARRAY tables LOOP
RETURN QUERY EXECUTE format('
SELECT this, that
FROM %I
WHERE this = $1', tbl)
USING cond;
END LOOP;
END
$BODY$
LANGUAGE plpgsql;
在这种情况下,我将tables
放在最后,以便为VARIADIC
参数设置一个开放式结尾。
拨打:
SELECT * FROM f_select_from_tbls2(4, 't1','t2','iLLegal name')