PostgreSQL中如何将表中的数据添加到最大对象查询

PostgreSQL中如何将表中的数据添加到最大对象查询,sql,postgresql,Sql,Postgresql,Postgres 9.1+数据库包含每个名为firma的公司和公司编号的不同模式,如firma1、firma5、firma99、firma12 每个架构都包含一个具有公司名称的表: -- this table contains always exactly one row: create table firma5.company ( company char(50) not null ); 以下查询列出了最大的对象: select (n.nspname||'.'||relname)::char

Postgres 9.1+数据库包含每个名为
firma
的公司和公司编号的不同模式,如
firma1、firma5、firma99、firma12

每个架构都包含一个具有公司名称的表:

-- this table contains always exactly one row:
create table firma5.company ( company char(50) not null );
以下查询列出了最大的对象:

select
(n.nspname||'.'||relname)::char(45) as tablename
    , pg_size_pretty(pg_total_relation_size(c.oid))::char(10) as totalsize
    , case
        when c.relkind='i' then 'index'
        when c.relkind='t' then 'toast'
        when c.relkind='r' then 'table'
        when c.relkind='v' then 'view'
        when c.relkind='c' then 'composite type'
        when c.relkind='S' then 'sequence'
        else c.relkind::text
      end ::char(14) as "type"
from
    pg_class c
    left join pg_namespace n on n.oid = c.relnamespace
    left join pg_tablespace t on t.oid = c.reltablespace
where
    (pg_total_relation_size(c.oid)>>20)>0 and c.relkind!='t'
order by
    pg_total_relation_size(c.oid) desc
此查询显示公司模式,如firma1、firma5等


如何在此查询结果中同时显示公司名称(
firman.company.company
)?查询也可以从除firmaN之外的模式返回表。在这种情况下,company name列应该为空或null。

这在普通SQL中是不可能的,因为您不能预先指定要连接的表名,所以需要运行动态查询。但是,如果架构具有公司表,则可以创建一个简单函数,从动态查询中返回公司名称:

CREATE FUNCTION company_name (sch text) RETURNS text AS $$
DECLARE
  comp text := NULL;
BEGIN
  IF strpos(sch, 'firma') = 1 THEN
    EXECUTE 'SELECT company FROM ' || sch || '.company' INTO comp;
  END IF;
  RETURN comp;
END; $$ LANGUAGE plpgsql STRICT STABLE;
然后在查询中使用该函数:

select
      (n.nspname||'.'||c.relname)::char(45) as tablename
    , pg_size_pretty(pg_total_relation_size(c.oid))::char(10) as totalsize
    , case
        when c.relkind='i' then 'index'
    --    when c.relkind='t' then 'toast' FILTERED OUT IN WHERE CLAUSE
        when c.relkind='r' then 'table'
        when c.relkind='v' then 'view'
        when c.relkind='c' then 'composite type'
        when c.relkind='S' then 'sequence'
        else c.relkind::text
      end ::char(14) as "type"
    , company_name(n.nspname) as company  -- <<<<<<<<<<<<<<<<<<<<<<<
from pg_class c
left join pg_namespace n on n.oid = c.relnamespace
--left join pg_tablespace t on t.oid = c.reltablespace NOT USED
where (pg_total_relation_size(c.oid)>>20)>0 and c.relkind!='t'
order by pg_total_relation_size(c.oid) desc;
选择
(n.nspname | |'。| | c.relname)::char(45)作为表名
,pg_size_pretty(pg_total_relationship_size(c.oid)):char(10)作为totalsize
案例
当c.relkind='i'然后是'index'
--当c.relkind='t'时,WHERE子句中过滤掉了'toast'
当c.relkind='r'然后是'table'
当c.relkind='v'然后是'view'
当c.relkind='c'时,则为'composite type'
当c.relkind='S'然后是'sequence'
else c.relkind::text
结束::字符(14)作为“类型”
,公司名称(n.nspname)为公司--