我正在使用Oracle数据库,尝试计算列中的非空值并按行类型报告结果。请帮助,我经常因SQL的力量而感到谦卑。
我有一份财务报表表单数据表:第1列是表单类型,列2..900(严重来说非常宽)具有空值或数字。所以我试图通过表单类型来表征非空值。
表t1的示例片段 - 仅显示2但有8种表单类型:
ftype c1 c2 c3 c4 c5
----- -- -- -- -- --
a 1 2 3 null null
b null null null 4 5
b null null null 44 55
所需报告如下;数字是上面样本表中的非空计数:
a b
-- --
c1 1 0
c2 1 0
c3 1 0
c4 0 2
c5 0 2
通过此报告,我们可以说"嘿,第4列永远不会填写表格A"。
如果我用程序编程语言解决问题,我会写下面的内容。然后我将结果作为一个大表发出:
for FORM in FormA .. FormH
for COLUMN in Col1 .. Col900
select count(*) from t1 where ftype = '${FORM}' and ${COLUMN} is not null;
end for
end for
SO的这些帖子向我指出CASE结构,但不完全相同:
Count number of NULL values in each column in SQL
Counting non-null columns in a rather strange way
我还为这个问题创建了一个SQL小提琴:http://sqlfiddle.com/#!2/e4d43/2
聪明的方式是什么?我是否必须编写大量SQL查询?提前谢谢。
更新1:感谢您的快速回复。我只需要这些信息,如果报告中的列数和类型都不在乎,请不要关心,解决方案是否更容易(即不需要支点)?以下对我来说很好,它会变得非常广泛,但我们应对:
c1 c2 c3 c4 c5
-- -- -- -- --
a 1 1 1 0 0
b 0 0 0 2 2
答案 0 :(得分:0)
SELECT ftype, sum(case when c1 is null then 0 else 1) C1Used,
sum(case when c2 is null then 0 else 1) C2Used,
sum(....
FROM Form
Group by ftype;
就是我这样做的方式。这将给你一个计数,零将是"不使用"将它写成900列,我想我会编写一个查询来为我写出来。
答案 1 :(得分:0)
如果您知道表单类型,则可以使用聚合查询执行此操作:
select ftype,
count(c1) as c1,
count(c2) as c2,
count(c3) as c3,
count(c4) as c4
from t1
group by ftype;
请注意count(<expression>)
计算<expression>
中的非NULL值。这是最简单的结果。如果您希望为每个列获取单独的行,并为每个ftype
获取单独的列,则查询会更加麻烦。这是一种方式:
select 'c1' as col,
sum(case when ftype = 'a' and c1 is not null then 1 else 0 end) as a,
sum(case when ftype = 'b' and c1 is not null then 1 else 0 end) as b
from table1
union all
select 'c2' as col,
sum(case when ftype = 'a' and c2 is not null then 1 else 0 end) as a,
sum(case when ftype = 'b' and c2 is not null then 1 else 0 end) as b
from table1
union all
select 'c3' as col,
sum(case when ftype = 'a' and c3 is not null then 1 else 0 end) as a,
sum(case when ftype = 'b' and c3 is not null then 1 else 0 end) as b
from table1
union all
select 'c4' as col,
sum(case when ftype = 'a' and c4 is not null then 1 else 0 end) as a,
sum(case when ftype = 'b' and c4 is not null then 1 else 0 end) as b
from table1;