Dynami c Имена столбцов в PostgreSQL Запросе - PullRequest
0 голосов
/ 23 апреля 2020

Я предоставил запрос ниже, с которым я работаю. Я создаю перекрестную таблицу, которая суммирует показатели по каждому игроку - цели с начала года, цели QTD, цели MTD, цели WEEK 1, цели WEEK 2 и т. Д. c ... за 14-недельный период.

Текущий запрос позволяет мне сделать это, но я хочу, чтобы в качестве имени столбца вместо WEEK1, WEEK2 и т. Д. c ...

использовалась дата начала недели. пытаясь избежать необходимости вводить go в запрос и переименовывать каждое поле WEEK. Я чувствую, что должен быть динамичный c способ сделать это. Любая помощь приветствуется.

ТЕКУЩИЙ ВЫХОД

name| YTD | QTD | MTD | WEEK1
----|-----|-----|-----|-------
Bob |  5  |  3  |  2  |  1
Jim |  10 |  6  |  4  |  2
Gary|  7  |  4  |  1  |  0

ЖЕЛАЕМЫЙ ВЫХОД

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

1 Ответ

1 голос
/ 23 апреля 2020

Вы можете использовать расширение tablefunc. При этом вы можете создать динамическую c таблицу. Для объяснения я буду использовать tablefunc пример из postgresql руководства.

Здесь у нас есть таблица, в которой есть столбец, подобный вашей 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 запускает 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...