【问题标题】:postgresql count rows with special columnspostgresql 计算具有特殊列的行数
【发布时间】:2021-03-16 17:51:19
【问题描述】:

我的桌子是这样的:

表 1:

ident A B C D
1 2 1
2 3
3 1 2 1 5
4 4
5 4 1 3
6 3 2
7 3
8 1
9 1

现在我需要从该表中进行分析。 它应该看起来像:

表2:

name just_name
A 3
B 1
C 1
D 0

just_name 列计算 table1 中除 ident 列之外的其他列中没有其他条目的列。 在真实表中,有超过 4 列,所以我最好不要在每列中使用 where。 :)

谢谢

【问题讨论】:

  • 我认为A 的输出可能是 3,正如我从输入表中看到的那样。
  • 你是对的。我更正了。
  • 列数不固定,行数固定?总是 9 点吗?

标签: sql postgresql select counting


【解决方案1】:

如果您可以将列名放在列列表中,那么下面的查询可以获得您想要的结果。尽管可以使这些部分动态化,但是如果您知道列名并且它不会动态更改,这将是更好的方法。如果你想要帽子部分动态的 olso,请告诉我。

架构:

create table mytable1(ident int, A int, B int, C int, D int);
insert into mytable1 values(1,null,2,1,null);
insert into mytable1 values(2,3,null,null,null);
insert into mytable1 values(3,1,2,1,5);
insert into mytable1 values(4,null,4,null,null);
insert into mytable1 values(5,4,1,null,3);
insert into mytable1 values(6,null,3,2,null);
insert into mytable1 values(7,null,null,3,null);
insert into mytable1 values(8,1,null,null,null);
insert into mytable1 values(9,1,null,null,null);

查询:

with cte as (SELECT
   unnest(array['A', 'B', 'C','D']) AS Columns,
   unnest(array[A, B, C,D]) AS Values,
   row_number()over(order by 1)rn
FROM mytable1),
cte2 as (
select rn,max(cte.columns)col,count(*) from cte   
 where values is not null
group by rn
having count(*)=1)
select distinct columns as name,coalesce(just_name,0)  from  cte left join (select col,count(rn) just_name from cte2
group by col)t on cte.columns=t.col

输出:

name coalesce
A 3
C 1
D 0
B 1

db小提琴here

【讨论】:

    【解决方案2】:

    我会这样做:

    select count(*) filter (where A is not null and B is null and C is null and d is null),
           count(*) filter (where A is null and B is not null and C is null and d is null),
           count(*) filter (where A is null and B is null and C is not null and d is null),
           count(*) filter (where A is null and B is null and C is null and d is not null)       
    from t;
    

    你也可以这样表达:

    select c.colname, count(*) filter (where c.num_vals = 1)
    from t cross join lateral
         (select colname, count(colval) over () as num_vals
          from (values ('a', t.a), ('b', t.b), ('c', t.c), ('d', t.d)) v(colname, colval)
          group by colname
         ) c
    group by c.colname;
    

    这会在单独的行中返回值。而且更容易概括。

    【讨论】:

    • 但如果我从 A 到 Z 都拥有它就不会像这样工作。
    • @hahakomisch 。 . .你会有不同的问题。这回答了这里提出的问题。
    猜你喜欢
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多