SQL:多列的直方图

时间:2020-04-22 09:31:51

标签: sql

给出下表:

Column A     Column B
    east          red
    west         blue
    east        green

我想找出每列的列值以及表中每个值出现多少次。鉴于结果上方的输出应如下所示:

A values   A value counts   B values   B value counts
    east                2        red                1
    west                1       blue                1
                               green                1

这可以通过为每列运行SELECT colX, count(colX) From Table GROUP BY colX来实现。如果存在复杂的WHERE条件,则这不是可伸缩的解决方案,因为需要针对每个查询执行该条件。

另一种方法是在查询中执行一次复杂的查询,然后计算服务器代码中的聚合。但是,有没有一个可以计算出来的SQL查询?

3 个答案:

答案 0 :(得分:0)

您可以使用窗口功能:

select cola, count(*) over (partition by cola) as a_count,
       colb, count(*) over (partition by colb) as b_count

这将在两列(a & b)中显示,并显示其值。

答案 1 :(得分:0)

您可以使用子查询进行汇总,然后union all并再次进行汇总以合并结果:

select max(a) as a, max(a_cnt) as a_cnt, max(b) as b, max(b_cnt) as b
from ((select a, count(*) as a_cnt, null as b, null as b_cnt,
              row_number() over (order by count(*) desc) as seqnum
       from t
       group by a
      ) union all
      (select null, null, b, count(*),
              row_number() over (order by count(*) desc) as seqnum
       from t
       group by b
      ) 
     ) ab
group by seqnum
order by seqnum;

答案 2 :(得分:0)

如果您使用的是Oracle,则可以使用user_tab_cols为表中的所有列生成SQL

        SELECT 'SELECT '
           || Listagg(column_name
                      ||',count(1) over (partition by '
                      ||column_name
                      ||') as '
                      ||column_name
                      ||'_cnt', ',')
                within GROUP (ORDER BY column_id)
           ||' FROM '
           ||'TEST_DATA'
    FROM   user_tab_cols
    WHERE  table_name = 'TEST_DATA' 

样品输出低于

 SELECT ID,count(1) over (partition by ID) as ID_cnt,VALUE,count(1) over (partition by 
 VALUE) as VALUE_cnt FROM TEST_DATA