将相同的聚合应用于表中的每个列

时间:2013-01-14 05:50:48

标签: sql postgresql postgresql-8.3

我正在使用专有的mpp数据库,该数据库已被分离psql 8.3。我试图将一个简单的计数应用到一个宽表(大约450列),所以我想知道是否最好的方法来做一个简单的SQL函数。我只计算给定列中的不同值的数量以及列中空值的数量。我想要为每列概括的查询是例如

如果我想针对我写的列名运行查询

select
count(distinct names) d_names,
sum(case when names is not null then 1 else 0 end) n_s_ip
from table; 
  

如果列数为450而不用手写出每个列名,我如何推广上面的查询来迭代表中的每一列?

2 个答案:

答案 0 :(得分:3)

首先,由于COUNT()仅计算非空值,因此可以简化查询

SELECT count(DISTINCT names) AS unique_names
      ,count(names) AS names_not_null
FROM   table;

但这是非null 值的数量,与您的描述相矛盾:

  

中空值的数量

对于 ,您将使用:

count(*) - count(names) AS names_null

由于count(*)计算所有行,count(names)只计算非空names行。 在@Andriy暗示之后删除了劣等替代。

自动 所有列动态地从目录表pg_attribute构建SQL语句。您可以在PL / pgSQL函数中使用EXECUTE来立即执行它。查找完整的代码示例,其中包含手册的链接以及与这些密切相关的问题的解释:

答案 1 :(得分:1)

您可以使用information_scheam.columns生成查询的重复部分。

select 'count(distinct '||column_name||') d_names, sum(case when '||column_name||' is not null then 1 else 0 end) n_s_ip,' 
from information_schema.columns where table_name='table'
order by ordinal_position;

以上查询会为count(...)的每列生成sum(...)table。此结果可用作查询的选择列表。您可以将结果剪切并粘贴到以下查询中:

select 
-- paste here
from table;

粘贴后,您必须删除最后一个逗号。

通过这种方式,您可以避免为450列编写select-list