数据透视表的有效方法

Posted

技术标签:

【中文标题】数据透视表的有效方法【英文标题】:Efficient way to pivot table 【发布时间】:2019-12-13 13:30:32 【问题描述】:

我有一个名为monthly_agg 的表,其中包含每月汇总数据。

+------------+-----+----------+-----------+---------------+--------------+-------------+----------+---------+
| yyyy_mm_dd | id  | app      | ex_status | active_status | active_count | active_base | ex_count | ex_base |
+------------+-----+----------+-----------+---------------+--------------+-------------+----------+---------+
| 2019-01-31 | 123 | content  | impl      | impl          | 390          | 321         | 344      | 340     |
+------------+-----+----------+-----------+---------------+--------------+-------------+----------+---------+
| 2019-01-31 | 333 | messages | impl      | impl          | 541          | 210         | 788      | 610     |
+------------+-----+----------+-----------+---------------+--------------+-------------+----------+---------+
| 2019-01-31 | 832 | photos   | no        | no            | null         | 430         | null     | 100     |
+------------+-----+----------+-----------+---------------+--------------+-------------+----------+---------+

我想让每个应用都成为一个专栏。每个应用列应包含一个百分比,计算如下:

SELECT 
    yyyy_mm_dd,
    id,
   App,
    SUM(CASE
        WHEN (app = ‘content’ AND ex_status = ‘impl’) THEN ex_count/ex_base
        WHEN (active_status = 'impl') THEN active_count/active_base
    END) AS percentage
FROM 
    monthly_agg

我需要让每个 app 值成为一列,然后该列的值是上述计算的结果。我怎么能以这种方式旋转桌子?理想情况下,我的输出如下所示:

+------------+-----+--------------------+---------------------+
| yyyy_mm_dd | id  | content_percentage | messages_percentage |
+------------+-----+--------------------+---------------------+
| 2019-01-31 | 123 | 1.2                | null                |
+------------+-----+--------------------+---------------------+
| 2019-01-31 | 333 | null               | 2.57                |
+------------+-----+--------------------+---------------------+

我有大约 20 个应用程序,所以动态会很棒。

【问题讨论】:

【参考方案1】:

IIUC 你可以试试:

SELECT 
    yyyy_mm_dd,
    id,
    SUM(CASE WHEN (app = 'content' AND ex_status = 'impl') THEN ex_count/ex_base 
WHEN (app = 'content' and active_status = 'impl') THEN active_count/active_base ELSE 0 END) AS content_percentage,
    SUM(CASE WHEN (app = 'messages' and active_status = 'impl') THEN active_count/active_base ELSE 0 END) AS messages_percentage
FROM 
    monthly_agg
GROUP BY
    yyyy_mm_dd, id

【讨论】:

使用这种方法,我需要为每个app 提供一个案例陈述。如果将来添加更多,则需要修改查询。有没有办法更动态地实现这一点? 嗯,我会将 shell 与 hive 结合起来,或者(更好的解决方案)使用 pyspark/pandas。 Hive 本身不会为您提供这种通用方法。 HiveQL 不支持您描述的动态枢轴。如果你想做这样的事情,你需要使用直接的动态 SQL 并在你使用的任何编排工具中构造查询。就我个人而言,我一直在 Spark 中完成这种类型的查询构造,我用它来驱动我的所有操作。 这就是我所说的 :) 或者 bash + hive 也可以

以上是关于数据透视表的有效方法的主要内容,如果未能解决你的问题,请参考以下文章

快速取消数据透视表的分类汇总行和总计行

当我尝试在 laravel 中更新数据透视表的内容时,有啥方法可以解决非法偏移类型错误

如何刷新数据透视图

Excle数据透视表如何移动数据透视表的位置

使用 Excel 数据透视表作为另一个数据透视表的数据源

分类汇总和数据透视表的优缺点