Postgresql - сводная таблица с кросс-таблицей или альтернатива? - PullRequest
0 голосов
/ 15 марта 2019

У меня есть следующая таблица:

enter image description here

Я хочу повернуть это и получить следующий результат:

  Table_name        Column_name      Values         ddmf_etl_id
"PROFITCENTERID"    "CO_AREA"       "DE02"           16807487
"PROFITCENTERID"    "PROFIT_CTR"    "0000001119"     16807487
"PROFITCENTERID"    "CO_AREA"       "DE02"           16807488
"PROFITCENTERID"    "PROFIT_CTR"    "0000001120"     16807488

К сожалению, мне не удалось сделать это со следующим выбором, поскольку CROSSTAB имеет ограниченное количество (3) аргументов:

SELECT  'PROFITCENTERID' AS table_name,t.*
FROM   

crosstab(

        'SELECT unnest(''{CO_AREA,PROFIT_CTR}''::text[]) AS col
             , row_number() OVER ()
             , unnest(ARRAY[CO_AREA::text,PROFIT_CTR::text]) AS val
        FROM   "1".PROFITCENTER_PROFITCENTERID'

   ) t (column_name text,  values text);

Результат оператора выбора (неверный):

enter image description here

Есть ли другие альтернативы Crosstab в Postgresql? Или, возможно, это можно сделать с помощью Crosstab?

Любая помощь приветствуется! Спасибо!

1 Ответ

1 голос
/ 15 марта 2019

Используйте unnest(), чтобы удвоить каждую строку и выбрать соответствующие значения:

select
    'profitcenterid' as table_name,
    unnest(array['co_area', 'profit_ctr']) as column_name,
    unnest(array[co_area, profit_ctr]) as value,
    ddmf_etl_id as ddmf_etl_id
from profitcenter_profitcenterid

   table_name   | column_name |   value    | ddmf_etl_id 
----------------+-------------+------------+-------------
 profitcenterid | co_area     | de02       |    16807487
 profitcenterid | profit_ctr  | 0000001119 |    16807487
 profitcenterid | co_area     | de02       |    16807488
 profitcenterid | profit_ctr  | 0000001120 |    16807488
(4 rows)    

Живая демоверсия в rextester.

Однако, это не очень помогает получить ожидаемый результат JSON. Вы хотите получить произвольные имена ключей, поэтому нет способа автоматически сгенерировать объекты на основе результата подзапроса. Их можно создать с помощью примитива jsonb_build_object():

select to_jsonb(s)
from (
    select
        'profitcenterid' as table_name,
        17 as type,
        '' as value,
        jsonb_build_array(
            jsonb_build_object('name', 'co_area', 'value', co_area, 'type', 0, 'children', '[]'::jsonb),
            jsonb_build_object('name', 'profit_ctr', 'value', profit_ctr, 'type', 0, 'children', '[]'::jsonb)
        ) as children
    from profitcenter_profitcenterid
    ) s

Пример в rextester.

Как примечание, ожидаемая структура кажется излишне сложной, простота - это достоинство.

...