Sql 如何创建;"统计数字";对于模式的每个表?(其中“统计”表示每个表返回1条记录)

Sql 如何创建;"统计数字";对于模式的每个表?(其中“统计”表示每个表返回1条记录),sql,postgresql,statistics,Sql,Postgresql,Statistics,我有一个模式myschema,其中有几十个表,每个表都包含一个特定的列maincolumn。我想创建整个模式的统计信息,在这里我可以看到每个表的main列中有多少不同的值 我知道,通过此查询,我可以在架构中列出表: SELECT tablename FROM pg_tables WHERE schemaname = 'myschema' 结果: tablename --------- table1 table2 table3 ... count ----- 2972 我还可以为每个表运

我有一个模式
myschema
,其中有几十个表,每个表都包含一个特定的列
maincolumn
。我想创建整个模式的统计信息,在这里我可以看到每个表的
main列中有多少不同的值

我知道,通过此查询,我可以在架构中列出表:

SELECT tablename 
FROM pg_tables 
WHERE schemaname = 'myschema'
结果:

tablename
---------
table1
table2
table3
...
count
-----
2972
我还可以为每个表运行查询:

SELECT COUNT(DISTINCT(maincolumn))  
FROM myschema.table1
结果:

tablename
---------
table1
table2
table3
...
count
-----
2972
但我想知道是否有办法将这两个任务合并到一个查询中,结果是:

tablename | count
----------+------
table1    | 2972 
table2    |  542 
table3    | 1523 
....

一个不那么优雅的解决方案是列出我所有的表,将结果放在Excel表中,并使用
连接
函数为每个表创建一个
选择
查询,然后我可以逐行运行,但我更喜欢一种更简单的方法。

您需要动态SQL来实现这一点,可能在PL/pgSQL函数中,如下所示:

CREATE OR REPLACE FUNCTION table_counts() RETURNS TABLE (table_name text, count bigint)
   LANGUAGE plpgsql AS
$$BEGIN
   FOR table_counts.table_name IN
      SELECT t.table_name
      FROM information_schema.tables AS t
      WHERE t.table_schema = 'myschema'
        AND t.table_type = 'BASE TABLE'
   LOOP
      EXECUTE format(
                 'SELECT count(*) FROM myschema.%I',
                 table_counts.table_name
              ) INTO table_counts.count;

      RETURN NEXT;
   END LOOP;
END;$$;
而且,这是相当昂贵的

如果近似计数对您来说足够好,请尝试

SELECT c.relname, c.reltuples
FROM pg_catalog.pg_class AS c
   JOIN pg_catalog.pg_namespace AS n
      ON c.relnamespace = n.oid
WHERE n.nspname = 'myschema'
  AND c.relkind = 'r';

如果先运行
ANALYZE
,结果会更准确。

是的,看起来我必须编写一个函数。我尝试了你的代码,但它说
类型“regnamespace”不存在
。我检查了pg_catalog.pg_类中regnamespace列的类型,该类型是oid。无论如何,谢谢你的回答。我将尝试编写函数,完成后将其发布到这里。您必须使用旧的PostgreSQL版本。我已经修改了我的查询并添加了一个功能,如果您不介意费用的话,可以使用该功能。