在sql或配置单元中按列名分组的高效查询

fjaof16o  于 2021-06-26  发布在  Hive
关注(0)|答案(2)|浏览(310)

假设我有一个表,有两列m_1和m_2:

m1 | m2
 3 | 17
 3 | 18
 4 | 17
 9 | 9

我想得到一个有3列的表:
m是m的索引(在我的示例1或2中)
d是表中包含的数据。
计数是每个数据的出现次数,按值和索引分组。
在本例中,结果是:

m   | d | count
m_1 | 3 | 2
m_1 | 4 | 1
m_1 | 9 | 1
m_2 | 17| 2
m_2 | 18| 1
m_2 | 9 | 1

第一行可以读作“数据3在列m\u 1中出现2次”?
一个简单的解决方案是执行两次参数化查询,如下所示:

for (i in 1 .. 2) 
    SELECT CONCAT('m_', i), m_i, count(*) FROM table GROUP BY m_i

但是这个算法扫描我的表两次。这是一个问题,因为我有255列m和bilion行。
如果我使用hive而不是关系数据库,解决方案会变得更简单吗?

bvk5enib

bvk5enib1#

posexplode(数组(m1,m2))

select      concat('m_',cast(pe.pos+1 as string))   as m
           ,pe.val                                  as d
           ,count(*)                                as `count` 

from        mytable t 
            lateral view posexplode(array(m1,m2)) pe 

group by    pos
           ,val
;
+------+-----+--------+
|  m   |  d  | count  |
+------+-----+--------+
| m_1  | 3   | 2      |
| m_1  | 4   | 1      |
| m_1  | 9   | 1      |
| m_2  | 9   | 1      |
| m_2  | 17  | 2      |
| m_2  | 18  | 1      |
+------+-----+--------+
dsf9zpds

dsf9zpds2#

你可以用 union all 以及 group by :

select colname, d, count(*)
from ((select 'm_1' as colname, m1 as d from t) union all
      (select 'm_2' as colname, m2 as d from t) 
     ) m12
group by colname, d;

相关问题