在PostgreSQL中,是否可以查询给定数据库中的所有表以获得满足某些条件的记录?
Select [dbname "db"] *
From [all tables in database "db"]
Where [some condition on records]
[]中的内容是任意的,直到它们通常应具有的含义为止。
谢谢。
答案 0 :(得分:2)
这里最好的选择是,您希望返回特定数据库中满足特定条件的每个表的所有行。这变得棘手,因为:
考虑一个包含两个表的数据库/方案,两个表的列都为F1
。我们希望该模式中F1=1
中的表中的所有记录。所以:
# CREATE TABLE public.t2 (f1 int, f2 varchar(20), f3 date);
CREATE TABLE
# CREATE TABLE public.t1 (f1 int, f4 varchar(40), f5 varchar(10), f6 int);
CREATE TABLE
# SELECT * FROM information_schema.tables WHERE table_schema = 'public';
table_catalog | table_schema | table_name | table_type | self_referencing_column_name | reference_generation | user_defined_type_catalog | user_defined_type_schema | user_defined_type_name | is_insertable_into | is_typed | commit_action
---------------+--------------+------------+------------+------------------------------+----------------------+---------------------------+--------------------------+------------------------+--------------------+----------+---------------
username | public | t2 | BASE TABLE | | | | | | YES | NO |
username | public | t1 | BASE TABLE | | | | | | YES | NO |
(2 rows)
# SELECT 'SELECT * FROM public.' || table_name || ' WHERE f1=1;' FROM
information_schema.tables WHERE table_schema = 'public';
?column?
-------------------------------------
SELECT * FROM public.t2 WHERE f1=1;
SELECT * FROM public.t1 WHERE f1=1;
(2 rows)
最后一条SQL生成两条记录(对于架构中的每个表一条记录),查询它的条件为true的记录。现在,您可以分别执行每个操作以获取结果(在两个结果集中)。
# SELECT * FROM public.t2 WHERE f1=1;SELECT * FROM public.t1 WHERE f1=1;
f1 | f2 | f3
----+----+----
(0 rows)
f1 | f4 | f5 | f6
----+----+----+----
(0 rows)
如果架构中的每个表都完全相同(相同的列数,列的顺序和数据类型),则可以查询information_Schema
并构建一个UNION查询,然后分别执行:
# CREATE TABLE public.t1 (f1 int, f2 varchar(20), f3 date);
CREATE TABLE
# CREATE TABLE public.t2 (f1 int, f2 varchar(20), f3 date);
CREATE TABLE
# INSERT INTO public.t1 VALUES (1, 'test', '2019-04-22'),(2, 'test2', '2019-04-22');
INSERT 0 2
# INSERT INTO public.t2 VALUES (1, 'testtest', '2019-04-21'),(2, 'testest2', '2019-04-20');
INSERT 0 2
# SELECT 'SELECT * FROM public.' || table_name || ' WHERE f1=1' || CASE WHEN LEAD(table_name) OVER (ORDER BY table_name) IS NOT NULL THEN ' UNION ALL' ELSE ';' END FROM information_schema.tables WHERE table_schema = 'public';
?column?
----------------------------------------------
SELECT * FROM public.t1 WHERE f1=1 UNION ALL
SELECT * FROM public.t2 WHERE f1=1;
(2 rows)
# SELECT * FROM public.t1 WHERE f1=1 UNION ALL
-# SELECT * FROM public.t2 WHERE f1=1;
f1 | f2 | f3
----+----------+------------
1 | test | 2019-04-22
1 | testtest | 2019-04-21
(2 rows)
您可以看到这两个选项都不是很漂亮,因为您必须动态编写SQL,然后分别执行它。