我有一个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中的问题。
答案 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
现在,无论您是否 应该 ,这都是另一回事。