3

我需要在几个表上执行相同的操作。现在查询看起来像这样:

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 上搜索它!

4

2 回答 2

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'
于 2013-01-31T18:29:07.100 回答
1

像@Igor desrcibes 这样视图 是一种选择。

如果性能至关重要并且您没有很多写入操作,则可以使用该视图来(重新)创建物化视图

或者,对于更短的语法和源表的动态选择,您可以使用这样的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值作为条件。

手册中有关循环数组的更多信息。手册中有关从函数返回的
更多信息。

使用动态 SQL,您必须警惕SQL 注入。这种威胁在这里通过两种方式消除:

  • 数组中的表名tables被注入了format()正确引用任何非标准表名的函数
  • 参数中的值按cond原样通过 via 传递USING,从而使 SQLi 不可能。

带参数的变体VARIADIC

目的是使函数调用更简单。您可以提交一个文本变量列表,而不是从它们构建一个数组(数组是从参数内部构建的)。就这样。

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')
于 2013-02-06T21:54:09.030 回答