[英]Get list of rows without any references in other tables in postgresql
I have a table that holds translations in an entire system and other tables reference to it, for example something like this: 我有一个表,可保存整个系统中的翻译,其他表也引用该表,例如:
Table "translations"
id | title
----------------------------
1 | First Translation
2 | Second Translation
And second table with foreign key pointing to translations
: 第二张表带有指向
translations
外键:
Table "article"
id | translation_id | ...
1 | 1 | ...
I would like to get a list of rows that are not referenced by any other table (in this example row with id=2). 我想获取没有任何其他表引用的行的列表(在此示例中,id = 2的行)。
Number of tables might change and I would like to have a general solution that will operate on native relations mechanism in psql. 表的数量可能会更改,我想有一个通用的解决方案,该解决方案可以在psql中的本机关系机制上运行。
I've made the function you need. 我已经完成了您需要的功能。 Bellow is the sample data I created to test it.
贝娄是我创建的用于测试的示例数据。 In my data sample the return should be the
ID 4
from the table t1
. 在我的数据样本中,返回值应该是表
t1
的ID 4
。 To your case the t1
table would be the translations
table. 根据您的情况,
t1
表将是translations
表。
You have to change it to your tables. 您必须将其更改为表格。 It shouldn't be difficult.
应该不难。
create table t1 (
id integer primary key not null,
lang varchar(10)
);
create table t2 (
id integer primary key not null,
id_t1 integer,
constraint fk_t2 foreign key (id_t1) references t1(id)
);
create table t3 (
id integer primary key not null,
id_t1 integer,
constraint fk_t3 foreign key (id_t1) references t1(id)
);
insert into t1 values (1, 'pt'), (2, 'us'), (3,'cn'), (4,'uk');
insert into t2 values (1, 1), (2,2);
insert into t3 values (1, 1), (2,3);
CREATE OR REPLACE FUNCTION listAllReferences()
RETURNS setof integer AS
$$
declare
fullSQL text;
rs RECORD;
begin
fullSQL := '';
for rs in
SELECT 'select t1.id from t1 inner join ' || tc.table_name || ' ON ('||tc.table_name||'.'||kcu.column_name||' = t1.id)' as sel
FROM information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
WHERE constraint_type = 'FOREIGN KEY'
AND ccu.table_name='t1' loop
if fullSQL != '' then
fullSQL := fullSQL || ' union ';
end if;
fullSQL := fullSQL || rs.sel;
end loop;
return query
execute 'select t1.id
from t1 left join ('||fullSQL||') alltb on (t1.id = alltb.id)
where alltb.id is null';
return;
end;
$$
LANGUAGE plpgsql;
And to use it just do: 要使用它,只需执行以下操作:
select * from listAllReferences();
It will return: 它将返回:
listallreferences
4
Future tables with reference to your language table will also get covered because I'm getting the data from the INFORMATION_SCHEMA
of PostgreSQL 将来涉及您的语言表的表也将涵盖在内,因为我是从PostgreSQL的
INFORMATION_SCHEMA
获取数据的
Also you may have to add another filter () to the query on the implicit cursor which is AND tc.table_schema = 'yourSchemaName'
另外,您可能还需要向隐式游标上的查询中添加另一个过滤器(),且为
AND tc.table_schema = 'yourSchemaName'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.