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

时间:2018-09-21 22:14:51

标签: sql amazon-redshift

我有一个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 个答案:

答案 0 :(得分:2)

至少您需要一次读取数据来确定需要哪些列,然后使用该信息动态编写新的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

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