[英]Sum by month and put months as columns
我每月都有時間序列數據,我想對每個ID進行求和,按月分組,然后將月份名稱作為列而不是行。
+----+------------+-------+-------+
| id | extra_info | month | value |
+----+------------+-------+-------+
| 1 | abc | jan | 10 |
| 1 | abc | feb | 20 |
| 2 | def | jan | 10 |
| 2 | def | feb | 5 |
| 1 | abc | jan | 15 |
| 3 | ghi | mar | 15 |
+----+------------+-----+-----+-----+
| id | extra_info | jan | feb | mar |
+----+------------+-----+-----+-----+
| 1 | abc | 25 | 20 | 0 |
| 2 | def | 10 | 5 | 0 |
| 3 | ghi | 0 | 0 | 15 |
我可以輕松地按月分組,總結價值觀。 這讓我:
-----------------------------------
| id | extra_info | month | value |
+----+------------+-------+-------+
| 1 | abc | jan | 25 |
| 1 | abc | feb | 20 |
| 2 | def | jan | 10 |
| 2 | def | feb | 5 |
| 3 | ghi | mar | 15 |
但我現在需要這幾個月作為列名。 不知道從哪里開始。
來自SQL大師的任何想法非常感謝!
您可以使用帶有CASE
表達式的聚合函數將行轉換為列:
select id,
extra_info,
sum(case when month = 'jan' then value else 0 end) jan,
sum(case when month = 'feb' then value else 0 end) feb,
sum(case when month = 'mar' then value else 0 end) mar,
sum(case when month = 'apr' then value else 0 end) apr,
sum(case when month = 'may' then value else 0 end) may,
sum(case when month = 'jun' then value else 0 end) jun,
sum(case when month = 'jul' then value else 0 end) jul,
sum(case when month = 'aug' then value else 0 end) aug,
sum(case when month = 'sep' then value else 0 end) sep,
sum(case when month = 'oct' then value else 0 end) oct,
sum(case when month = 'nov' then value else 0 end) nov,
sum(case when month = 'dec' then value else 0 end) "dec"
from yt
group by id, extra_info
我會用crosstab()
這件事。 如果您還沒有安裝附加模塊tablefunc
:
CREATE EXTENSION tablefunc
基礎知識:
PostgreSQL交叉表查詢
如何處理額外的列:
使用Tablefunc在多列上進行透視
高級用法:
使用CASE和GROUP BY進行數據透視的動態替代方法
CREATE TEMP TABLE tbl
(id int, extra_info varchar(3), month date, value int);
INSERT INTO tbl (id, extra_info, month, value)
VALUES
(1, 'abc', '2012-01-01', 10),
(1, 'abc', '2012-02-01', 20),
(2, 'def', '2012-01-01', 10),
(2, 'def', '2012-02-01', 5),
(1, 'abc', '2012-01-01', 15),
(3, 'ghi', '2012-03-01', 15);
我在基表中使用實際date
,因為我假設只是為了簡化你的問題而隱藏它。 但只有月份名稱, ORDER BY
就沒有了。
SELECT * FROM crosstab(
$$SELECT id, extra_info, to_char(month, 'mon'), sum(value) AS value
FROM tbl
GROUP BY 1,2,month
ORDER BY 1,2,month$$
,$$VALUES
('jan'::text), ('feb'), ('mar'), ('apr'), ('may'), ('jun')
, ('jul'), ('aug'), ('sep'), ('oct'), ('nov'), ('dec')$$
)
AS ct (id int, extra text
, jan int, feb int, mar int, apr int, may int, jun int
, jul int, aug int, sep int, oct int, nov int, dec int);
結果:
id | extra | jan | feb | mar | apr | may | jun | jul | aug | sep | oct | nov | dec
----+-------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
1 | abc | 25 | 20 | | | | | | | | | |
2 | def | 10 | 5 | | | | | | | | | |
3 | ghi | | | 15 | | | | | | | | |
安裝tablefunc模塊需要一些開銷和一些學習,但結果查詢更快,更短,更通用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.