SQL - 如何将按类别分组的指标值展平为单行?

Posted

技术标签:

【中文标题】SQL - 如何将按类别分组的指标值展平为单行?【英文标题】:SQL - How to flatten metric values grouped by category to a single row? 【发布时间】:2021-10-21 01:34:39 【问题描述】:

我想创建一个宽大的平面表格来显示不同类别的不同指标。但是通过以下方法,我得到了一个爆炸数据集。 创建一个宽表的正确方法是什么,其中每个指标都有一个对应的值?例如:(TOTAL_CAT_VALUE_SAMPLE_1 = 372.8, CAT_1_VALUE_SAMPLE_1 = 155.0, CAT_2_VALUE_SAMPLE_1=NULL, CAT_3_VALUE_SAMPLE_1=217.8) 等。

另外,有没有办法减少查询中的代码重复,这些查询仅在 WHERE 条件中定义的日期期间有所不同?

WITH metrics_sample_1 AS (SELECT 
    CATEGORY,
    SUM(METRIC_VALUE * COEFF) AS TOTAL_CAT_VALUE_SAMPLE_1,
    SUM(CASE WHEN CATEGORY = 'CAT_1' THEN METRIC_VALUE * COEFF ELSE 0 END) AS CAT_1_VALUE_SAMPLE_1,
    SUM(CASE WHEN CATEGORY = 'CAT_2' THEN METRIC_VALUE * COEFF ELSE 0 END) AS CAT_2_VALUE_SAMPLE_1,
    SUM(CASE WHEN CATEGORY = 'CAT_3' THEN METRIC_VALUE * COEFF ELSE 0 END) AS CAT_3_VALUE_SAMPLE_1,
    COUNT(DISTINCT CAT_ID) AS CAT_ID_COUNT_SAMPLE_1
    FROM METRICS_DATA
    WHERE ACTION_DATE > (DATEADD(DAY, -10, GETDATE()))
    GROUP BY CATEGORY
    ),

    metrics_sample_2 AS (SELECT 
    CATEGORY,
    SUM(METRIC_VALUE * COEFF) AS TOTAL_CAT_VALUE_SAMPLE_2,
    SUM(CASE WHEN CATEGORY = 'CAT_1' THEN METRIC_VALUE * COEFF ELSE 0 END) AS CAT_1_VALUE_SAMPLE_2,
    SUM(CASE WHEN CATEGORY = 'CAT_2' THEN METRIC_VALUE * COEFF ELSE 0 END) AS CAT_2_VALUE_SAMPLE_2,
    SUM(CASE WHEN CATEGORY = 'CAT_3' THEN METRIC_VALUE * COEFF ELSE 0 END) AS CAT_3_VALUE_SAMPLE_2,
    FROM METRICS_DATA
    WHERE ACTION_DATE BETWEEN DATEADD(DAY, -20, GETDATE()) and DATEADD(DAY, -10, GETDATE())    
    GROUP BY CATEGORY
    )

SELECT * FROM metrics_sample_1

(当我从 metrics_sample_1 和 metrics_sample_2 中进行选择时,表格会更加爆炸)

+------------+---------------------------+----------------------+----------------------+--------------+
| CATEGORY   | TOTAL_CAT_1_VALUE_SAMPLE_1| CAT_1_VALUE_SAMPLE_1 | CAT_2_VALUE_SAMPLE_1 | CAT_3_VALUE_SAMPLE_1 |
+------------+---------------------------+----------------------+----------------------+--------------+
| CAT_1      | 155.0                     | 155.0                | 0.0                  | 0.0         |
| CAT_2      | NULL                      | 0.0                  | NULL                 | 0.0            |
| CAT_3      | 217.8                     | 0.0                  | 0.0                  | 217.8        |
+------------+---------------------------+----------------------+----------------------+--------------+

我想达到以下结果:

+----------------------+-------------------+------------+-----------------+-----------------------+
| TOTAL_CAT_1_VALUE_SAMPLE_1  | CAT_1_VALUE_SAMPLE_1| CAT_2_VALUE_SAMPLE_1 | CAT_3_VALUE_SAMPLE_1 |
+-----------------------------+---------------------+------------+-----------------------------+
| 372.8                       | 155.0               | NULL       |          217.8
+-----------------------------+-------------------------+-----------------+--------------------+

【问题讨论】:

【参考方案1】:

如果你只想要一行,那么你不需要GROUP BY

SELECT SUM(METRIC_VALUE * COEFF) AS TOTAL_CAT_VALUE_SAMPLE_1,
       SUM(CASE WHEN CATEGORY = 'CAT_1' THEN METRIC_VALUE * COEFF ELSE 0 END) AS CAT_1_VALUE_SAMPLE_1,
       SUM(CASE WHEN CATEGORY = 'CAT_2' THEN METRIC_VALUE * COEFF ELSE 0 END) AS CAT_2_VALUE_SAMPLE_1,
       SUM(CASE WHEN CATEGORY = 'CAT_3' THEN METRIC_VALUE * COEFF ELSE 0 END) AS CAT_3_VALUE_SAMPLE_1,
      COUNT(DISTINCT CAT_ID) AS CAT_ID_COUNT_SAMPLE_1
FROM METRICS_DATA
WHERE ACTION_DATE > DATEADD(DAY, -10, GETDATE());

【讨论】:

以上是关于SQL - 如何将按类别分组的指标值展平为单行?的主要内容,如果未能解决你的问题,请参考以下文章

将 JSON 文档展平为单行

as.data.frame 将嵌套列表展平为单行,而不是为每条记录创建行 [重复]

如何使用 sql 和按日期分组显示指标在日期上的累积增长?

如何将元组列表展平为pythonic列表[重复]

将按月分组的行计数为列

Mysql union如何将返回的3行分组为单行