动态地将行旋转到红移中的列

Posted

技术标签:

【中文标题】动态地将行旋转到红移中的列【英文标题】:pivot rows to columns in redshift dynamically 【发布时间】:2018-09-21 22:14:50 【问题描述】:

我有一个包含不同案例、公司和日期(时间戳)的 Redshift 表

我使用以下查询按月汇总每个公司的案例数:

      SELECT
    DATE_TRUNC('MONTH', case_date) AS month,
    company_id,
    COUNT(DISTINCT case_number)      AS case_count
  FROM case
  WHERE case_date >= '2017-01-01'
  AND case_date < DATE_TRUNC('MONTH', CURRENT_DATE)
  GROUP BY 1, 2
  ORDER BY 1

得到:

month                  company_id       case_count
2017-01-01 00:00:00     5786            4
2017-01-01 00:00:00     8681            1
.........               ....         .....
2018-08-01              ....         .....      

我想按公司对表格进行透视。期望的输出是让每家公司在一行中,列是从 2017-01-01 到当前日期的上一个月的每个月。所以它看起来像:

  company_id   2017-01-01_case_count  2017-02-01_case_count  .. 2018-08-01..
    5786          4                        7

我检查了许多使用 CASE 的解决方案,但我认为这不是我的解决方案,因为我有很多不同的月份。我还希望解决方案是动态的,这样以后我就不必随着时间的推移返回并更改我的查询。

我当然可以将所有数据转储到 Python 中并执行此操作,但我想在 Redshift 中解决问题。

【问题讨论】:

【参考方案1】:

至少您需要读取一次数据以确定您需要哪些列,然后使用该信息动态编写新的 sql,然后运行它。

这是必要的,因为 SQL 的结构要求查询/数据集具有固定签名(列名、数据类型、ets)而不是动态签名(没有本地 sql 可以满足您的要求) .对于您开始使用的标准化结构,这很好。

这也意味着 SQL 不是通常是重新格式化数据以呈现给人类的正确位置。这就是您的表示层应该做的。

在您的情况下,您似乎从WHERE 子句中的参数中知道了您想要的列。这意味着您的 python 可以仅根据这些参数编写动态 SQL...

SELECT
  company_id,
  COUNT(DISTINCT CASE WHEN case_date >= '2017-01-01' AND case_date < '2017-02-01' THEN case_number END)   AS 201701_case_count,
  COUNT(DISTINCT CASE WHEN case_date >= '2017-02-01' AND case_date < '2017-03-01' THEN case_number END)   AS 201702_case_count,
  ...
  COUNT(DISTINCT CASE WHEN case_date >= '2018-09-01' AND case_date < '2018-10-01' THEN case_number END)   AS 201809_case_count
FROM
  case
WHERE
      case_date >= '2017-01-01'
  AND case_date <  DATE_TRUNC('MONTH', CURRENT_DATE)
GROUP BY
  company_id

现在,无论您是否应该,这是另一回事。

【讨论】:

以上是关于动态地将行旋转到红移中的列的主要内容,如果未能解决你的问题,请参考以下文章

PIVOT 动态地将行旋转到列中

红移中的 juliandate 到 normaldate

红移中的完全外连接

亚马逊红移中的上次更新查询计数

红移中的长真空

红移中的 PERCENTILE_CONT()