[英]Dynamic Column Names in PostgreSQL Query
我在下面提供了我正在使用的查询。 我正在创建一个交叉表,汇总每个玩家的指标 - YTD 目标、QTD 目标、MTD 目标、第 1 周目标、第 2 周目标等……在滚动的 14 周期间。
当前查询允许我这样做,但我希望将星期开始日期作为列名而不是 WEEK1、WEEK2 等...
显然,我试图避免将 go 放入查询中并为每个 WEEK 字段重新命名。 我觉得应该有一种动态的方式来做到这一点。 任何帮助表示赞赏。
当前 OUTPUT
name| YTD | QTD | MTD | WEEK1
----|-----|-----|-----|-------
Bob | 5 | 3 | 2 | 1
Jim | 10 | 6 | 4 | 2
Gary| 7 | 4 | 1 | 0
期望 OUTPUT
name| YTD | QTD | MTD | 4/20/2020
----|-----|-----|-----|-------
Bob | 5 | 3 | 2 | 1
Jim | 10 | 6 | 4 | 2
Gary| 7 | 4 | 1 | 0
--load roster
with a as(
select
a.id,
a.name,
from roster)
-- total goals YTD
b as (
select
id,
sum(goals) as goals
FROM [games]
WHERE created_date > '2020-01-01'
GROUP BY 1
),
-- total goals QTD
c as (
select
id,
sum(goals) as goals
FROM [games]
WHERE created_quarter = 'FY2021Q1'
GROUP BY 1
),
-- total goals MTD
d as (
select
id,
sum(goals) as goals
FROM [games]
WHERE date_trunc('month', date) = date_trunc('month', date)
GROUP BY 1
),
-- SET TIME FRAME - 14 WEEKS
e as (
select DISTINCT
[date:week] as week
FROM [games]
where date > current_date - interval '14 weeks'
ORDER BY 1 ASC
),
-- ADD ROW NUMBERS
ee as (
select
week,
ROW_NUMBER () OVER (ORDER BY week DESC) as rn
FROM e
),
-- ADD WEEK to Games
f as (
SELECT
*,
[created_date:week] as week_index
from [games]
),
-- week 1
g as (
SELECT
week_index,
id,
sum(goals) as goals
FROM f
inner join ee on f.week_index = ee.week AND rn = 1
GROUP BY 1,2
)
--MAIN QUERY
SELECT
a.name, -- player name
b.goals as YTD, -- goals YTD
c.goals as QTD, -- goals QTD
d.goals as MTD, -- goals MTD
g.goals as week1 -- goals for week 1 of time frame, this is what I want to change to 4/20/2020
from a -- roster
left join b on a.id = b.id -- YTD
left join c on a.id = c.id -- MTD
left join d on a.id = d.id -- QTD
left join g on a.id = g.id -- week1
您可以使用tablefunc
扩展。 有了这个,您可以创建一个动态表。 为了解释,我将使用 postgresql 手册的tablefunc
示例。
在这里,我们有一个表,其中有一列,如您的week
信息,将被转换为一列,以及需要在您的结果中显示的相关信息。
CREATE TABLE ct(id SERIAL, rowid TEXT, attribute TEXT, value TEXT);
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att1','val1');
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att2','val2');
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att3','val3');
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att4','val4');
INSERT INTO ct(rowid, attribute, value) VALUES('test2','att1','val5');
INSERT INTO ct(rowid, attribute, value) VALUES('test2','att2','val6');
INSERT INTO ct(rowid, attribute, value) VALUES('test2','att3','val7');
INSERT INTO ct(rowid, attribute, value) VALUES('test2','att4','val8');
基本上, crosstab
function 运行 SQL 并创建列,动态地使用列的值命名列,组合需要旋转的值。 因此,对于上面创建的表,结果将如下所示:
SELECT *
FROM crosstab(
'select rowid, attribute, value
from ct
where attribute = ''att2'' or attribute = ''att3''
order by 1,2')
AS ct(row_name text, category_1 text, category_2 text, category_3 text);
row_name | category_1 | category_2 | category_3
----------+------------+------------+------------
test1 | val2 | val3 |
test2 | val6 | val7 |
(2 rows)
并且,要显示已解析的列,您可以使用双引号,如下所示:
SELECT *
FROM crosstab(
'select rowid, attribute, value
from ct
where attribute = ''att2'' or attribute = ''att3''
order by 1,2')
AS ct(row_name text, "2020/01/01" text, "2020/07/01" text, "2020/12/01" text);
row_name | 2020/01/01 | 2020/07/01 | 2020/12/01
----------+------------+------------+------------
test1 | val2 | val3 |
test2 | val6 | val7 |
(2 rows)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.