2

我正在使用已分叉的专有 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,我如何概括上面的查询以遍历表中的每一列而不手动写出每个列名?

4

2 回答 2

3

首先,由于COUNT()只计算非空值,您的查询可以简化:

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

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

列中空值数量的计数

为此您将使用:

count(*) - count(names) AS names_null

由于count(*)计算所有行,并且count(names)仅计算具有非 null 的行names
在@Andriy 提示后删除了劣质替代品。

要为所有列自动执行此操作,请从目录表中动态构建 SQL 语句。您可以在 PL/pgSQL 函数中使用以立即执行它。在这些密切相关的问题下查找带有手册链接和解释的完整代码示例:pg_attributeEXECUTE

于 2013-01-14T06:14:40.567 回答
2

您可以使用 生成查询的重复部分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;

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

这样,您可以避免写入select-list450 列。

于 2013-01-14T06:18:21.937 回答