在Postgresql中,我想测试:
第一个查询
对于第一个查询,我执行以下操作:
select t1.table_name as t1_table_name, t2.table_name as t2_extra_tables_in_schema
from required_tables t1
right join information_schema.tables t2
on t1.table_name = t2.table_name
where t2.table_schema='Schema_X'
and t1.table_name IS NULL
这给了我所需的结果 - 即模式中的表不在 required_tables 表中。
第二个查询
但是,对于第二个查询,当我尝试以下操作时(相当于第一个查询,但这次使用左连接):
select t1.table_name as t1_tables_missing_from_schema, t2.table_name
from required_tables t1
left join information_schema.tables t2
on t1.table_name = t2.table_name
where t2.table_schema='Schema_X'
and t2.table_name IS NULL
我总是得到零结果,即使我知道 required_tables 中有一个表不在架构中。
所以,在读到“where”子句可能会搞乱连接(虽然我不明白为什么)后,我尝试了以下方法:
select t1.table_name as t1_tables_missing_from_schema, t2.table_name
from required_tables t1
left join information_schema.tables t2
on t1.table_name = t2.table_name
where t2.table_name IS NULL
这确实为我提供了 required_tables 中的表的名称,但不在架构中。
但是,假设相关表处于不同的模式中 - 在这种情况下,我不会从之前的查询中获得任何结果,因为该表会在其他模式中找到,而我不想检查该模式。
如何解决此问题并在第二个查询中使用 where t2.table_schema='Schema_X' ?
此外,如果有一种方法可以在单个查询中获取两个缺失的结果(我的猜测可能是完全外连接),那我也会感兴趣。
您可以或多或少地按照您描述问题的方式写出来
设置:
CREATE TEMP TABLE required_tables (table_name name);
INSERT INTO required_tables VALUES ('aaa'), ('bbb');
CREATE SCHEMA q;
CREATE TABLE q.aaa (i int);
CREATE TABLE q.ccc (i int);
查询:
WITH extra_tables AS (
SELECT t.table_name
FROM information_schema.tables t
WHERE table_schema='q'
EXCEPT
SELECT table_name
FROM required_tables
)
, missing_tables AS (
SELECT rt.table_name
FROM required_tables rt
EXCEPT
SELECT table_name fROM information_schema.tables WHERE table_schema='q'
)
SELECT 'extra' AS reason, et.table_name
FROM extra_tables et
UNION ALL
SELECT 'missing', mt.table_name
FROM missing_tables mt;
结果:
┌─────────┬────────────┐
│ reason │ table_name │
├─────────┼────────────┤
│ extra │ ccc │
│ missing │ bbb │
└─────────┴────────────┘
(2 rows)