SQL / Postgresql 统计多列有条件
SQL / Postgresql count multiple columns with conditions
我有一个简单的 table 形式:
id
性别
a_feature(布尔值)
b_feature(布尔值)
...
xyz_feature(布尔值)
我想根据性别对所有特征列求和。
公制
男
女
a_feature
345
3423
b_feature
65
143
...
...
...
xyz_feature
133
5536
有没有简单的方法可以做到这一点,例如使用 information_schema.
我只找到了下面的解决方案,但这很丑陋:
select
'a_feature' as feature_name,
count(case a_feature and gender = 'male') as male,
count(case a_feature and gender = 'female') as female
from table
union
select
b_feature as feature_name,
count(case b_feature and gender = 'male') as male,
count(case b_feature and gender = 'female') as female
from table
.
.
.
select
xyz_feature as feature_name,
count(case xyz_feature and gender = 'male') as male,
count(case xyz_feature and gender = 'female') as female
from table
您可以逆透视和聚合。一种方法是:
select name,
sum(case when feature and gender = 'male' then 1 else 0 end) as num_male,
sum(case when feature and gender = 'female' then 1 else 0 end) as num_female
from ((select 'a_feature' as name, a_feature as feature, gender
from t
) union all
(select 'b_feature' as name, b_feature, gender
from t
) union all
. . .
) f
group by name;
在 Postgres 中,您将使用横向连接取消透视:
select name,
sum(case when feature and gender = 'male' then 1 else 0 end) as num_male,
sum(case when feature and gender = 'female' then 1 else 0 end) as num_female
from t cross join lateral
(values ('a_feature', a_feature),
('b_feature', b_feature),
. . .
) v(name, feature)
group by name;
如果您不愿意全部输入,可以使用 information_schema.columns
为 values()
生成列表。
编辑:
您可以使用如下方式构造 values
子句:
select string_agg('(''' || column_name || ''', column_name)', ', ')
from information_schema.columns
where table_name = ?
我有一个简单的 table 形式:
id | 性别 | a_feature(布尔值) | b_feature(布尔值) | ... | xyz_feature(布尔值) |
---|
我想根据性别对所有特征列求和。
公制 | 男 | 女 |
---|---|---|
a_feature | 345 | 3423 |
b_feature | 65 | 143 |
... | ... | ... |
xyz_feature | 133 | 5536 |
有没有简单的方法可以做到这一点,例如使用 information_schema.
我只找到了下面的解决方案,但这很丑陋:
select
'a_feature' as feature_name,
count(case a_feature and gender = 'male') as male,
count(case a_feature and gender = 'female') as female
from table
union
select
b_feature as feature_name,
count(case b_feature and gender = 'male') as male,
count(case b_feature and gender = 'female') as female
from table
.
.
.
select
xyz_feature as feature_name,
count(case xyz_feature and gender = 'male') as male,
count(case xyz_feature and gender = 'female') as female
from table
您可以逆透视和聚合。一种方法是:
select name,
sum(case when feature and gender = 'male' then 1 else 0 end) as num_male,
sum(case when feature and gender = 'female' then 1 else 0 end) as num_female
from ((select 'a_feature' as name, a_feature as feature, gender
from t
) union all
(select 'b_feature' as name, b_feature, gender
from t
) union all
. . .
) f
group by name;
在 Postgres 中,您将使用横向连接取消透视:
select name,
sum(case when feature and gender = 'male' then 1 else 0 end) as num_male,
sum(case when feature and gender = 'female' then 1 else 0 end) as num_female
from t cross join lateral
(values ('a_feature', a_feature),
('b_feature', b_feature),
. . .
) v(name, feature)
group by name;
如果您不愿意全部输入,可以使用 information_schema.columns
为 values()
生成列表。
编辑:
您可以使用如下方式构造 values
子句:
select string_agg('(''' || column_name || ''', column_name)', ', ')
from information_schema.columns
where table_name = ?