繁体   English   中英

PostgreSQL 查询中的动态列名称

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM