Redshift. Как мы можем транспонировать (динамически) таблицу из столбцов в строки? - PullRequest
0 голосов
/ 05 сентября 2018

Как мы можем транспонировать таблицу Redshift из столбцов в строки?

Например, если у нас есть общая (еще не известная) таблица, подобная следующей:

source table:

date        id      alfa                beta                gamma   ...                 omega
2018-08-03  1       1                   2                   3                           4
2018-08-03  2       4                   3                   2                           1
...
2018-09-04  1       3                   1                   2                           4
...

Как мы можем добиться следующего результата?

transposed table:

date        id      column_name     column_value
2018-08-03  1       alfa            1
2018-08-03  1       beta            2
...
2018-08-03  2       omega           1
...
2018-09-04  1       gamma           2
...

Где целевая таблица, количество столбцов (альфа, бета, гамма, ..., омега) все являются динамическими (поэтому мы ищем решение, которое не отображало бы case when для каждого столбца необходимо, так как мы хотели бы применить это к нескольким различным таблицам).

Но у нас будут поля date и id во всех таблицах назначения (или, наконец, первичный ключ или ключ-кандидат во всех таблицах).

Наша версия Redshift:

PostgreSQL 8.0.2, Redshift 1.0.3380

Как мы можем это сделать?

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Вам необходимо жестко закодировать имена столбцов в запросе.

CREATE TABLE stack(date TEXT, id BIGINT, alpha INT, beta INT, gamma INT, omega INT);

INSERT INTO STACK VALUES('2018-08-03', 1, 1, 2, 3, 4);
INSERT INTO STACK VALUES('2018-08-03', 2, 4, 3, 2, 1);
INSERT INTO STACK VALUES('2018-08-04', 1, 3, 1, 2, 4);

SELECT
  date,
  id,
  col,
  col_value
FROM
(
SELECT date, id, alpha AS col_value, 'alpha' AS col FROM stack
UNION
SELECT date, id, beta  AS col_value, 'beta'  AS col FROM stack
UNION
SELECT date, id, gamma AS col_value, 'gamma' AS col FROM stack
UNION
SELECT date, id, omega AS col_value, 'omega' AS col FROM stack
) AS data
ORDER BY date, id, col

Результат:

2018-08-03  1   alpha   1
2018-08-03  1   beta    2
2018-08-03  1   gamma   3
2018-08-03  1   omega   4
2018-08-03  2   alpha   4
2018-08-03  2   beta    3
2018-08-03  2   gamma   2
2018-08-03  2   omega   1
2018-08-04  1   alpha   3
2018-08-04  1   beta    1
2018-08-04  1   gamma   2
2018-08-04  1   omega   4
0 голосов
/ 05 сентября 2018

Вместо того, чтобы не давать ответ в комментариях, вот полупсевдокод, чтобы объяснить, как я это сделал, дайте мне знать, если вам нужна дополнительная информация / уточнение

# dictionary to define your target structure
target_d = {'date':'','id':'','column_name':'','column_value':''}

# dictionary for source structure
source_d = {'date':'date','id':'id','column_name1':'','column_name2':''....}

с этим указанием выше вы объявляете, что если поле сопоставлено, оно не будет динамическим, все другие поля / столбцы будут поворачиваться, вы можете сделать его динамичным, используя исходную таблицу DDL

# assuming you already read your source data
# your while loop to go thru the coming data
while <your code here>
    # create a dict to process an incoming row
    curr_d = target_d.copy()

    curr_d['date'] = date from incoming record
    curr_d['id'] = id from incoming record

    # since we are going to create a row for each column name/value combos 
    # we need a new dict to hold the values

    out_d = curr_d

эта строка служит двум целям: создать новый dict для выходной строки и сохранить постоянную часть выходной строки (т. Е. Date и id)

    # rest of the fields are going to be pivoted now
    for afield in source_d:
        if afield not in source_d.values():
            curr_d['column_name'] = afield
            curr_d['column_value'] = column value from incoming record

        create a 'row' from your out_d dict
        write to output/ append to output data frame (if you use a data frame)

Хотя цикл будет проходить через исходные строки, цикл for создаст новую строку для каждого комбинированного имени / значения столбца для цели

Дайте мне знать, если это работает для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...