Значения сводных строк, соответствующие шаблону, в имена столбцов - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть данные, которые выглядят так:

OH_IDNR  OCV_VNAME                              OCV_VALUE
8420518  response_part_0_script_0_code_0        $[*].id
8420518  response_part_0_script_0_queryType     JSONPath
8420518  response_part_0_script_0_resourceName  profileIds#
8420518  response_part_0_script_0_saveTo        variable
8420518  response_part_0_script_0_useArray      TRUE
8420518  response_part_0_script_1_code_0        $[*].name
8420518  response_part_0_script_1_queryType     JSONPath
8420518  response_part_0_script_1_resourceName  profileNames#
8420518  response_part_0_script_1_saveTo        variable
8420518  response_part_0_script_1_useArray      TRUE
8420518  response_part_0_script_2_code_0        $[*].environment
8420518  response_part_0_script_2_queryType     JSONPath
8420518  response_part_0_script_2_resourceName  profileEnvironments#
8420518  response_part_0_script_2_saveTo        variable
8420518  response_part_0_script_2_useArray      TRUE
8420518  response_part_0_script_3_code_0        $[*].description
8420518  response_part_0_script_3_queryType     JSONPath
8420518  response_part_0_script_3_resourceName  profileDescriptions#
8420518  response_part_0_script_3_saveTo        variable
8420518  response_part_0_script_3_useArray      TRUE

Я хотел бы повернуть эти данные так, чтобы для каждого набора строк с одинаковым OH_IDNR и с одинаковой общей / неуникальной частью OCV_VNAME возвращаются эти столбцы:

  1. OH_IDNR
  2. Общая часть OCV_VNAME (например, 'response_part_0_script_0 _')
  3. - n. Один столбец для каждой уникальной части OCV_Name (например, 'resourceName'), со значением OCV_VALUE.

Например,

OH_IDNR  OCV_VNAME_common           code_0            queryType  resourceName          saveTo    useArray
8420518  response_part_0_script_0_  $[*].id           JSONPath   profileIds#           variable  TRUE
8420518  response_part_0_script_1_  $[*].name         JSONPath   profileNames#         variable  TRUE
8420518  response_part_0_script_2_  $[*].environment  JSONPath   profileEnvironments#  variable  TRUE
8420518  response_part_0_script_3_  $[*].description  JSONPath   profileDescriptions#  variable  TRUE

Это, очевидно, предполагает, что уникальная часть OCV_VNAME - это строка, подходящая для использования в качестве имени столбца. Я попробовал несколько вещей, но элегантное решение ускользает от меня.

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

Для меня это выглядит как совокупность:

select OH_IDNR,
       substr(OCV_VNAME, 1, 25) as OCV_VNAME_common,
       max(case when OCV_VNAME_common like '%code_0' then OCV_VALUE end) as code_0,
       max(case when OCV_VNAME_common like '%queryType' then OCV_VALUE end) as queryType,
       max(case when OCV_VNAME_common like '%resourceName' then OCV_VALUE end) as resourceName,
       max(case when OCV_VNAME_common like '%saveTo' then OCV_VALUE end) as saveTo,
       max(case when OCV_VNAME_common like '%useArray' then OCV_VALUE end) as useArray
from t
group by OH_IDNR, substr(OCV_VNAME, 1, 25);

Я бы подчеркнул, что это основано на ваших данных выборки. Неясно, есть ли лучший способ назначить префикс. Одна идея состоит в том, чтобы использовать регулярные выражения:

select OH_IDNR,
       regexp_replace(OCV_VNAME, '^(.*)(code_0|queryType|resourceName|saveTo|useArray)$', '\1'),
       max(case when OCV_VNAME_common like '%code_0' then OCV_VALUE end) as code_0,
       max(case when OCV_VNAME_common like '%queryType' then OCV_VALUE end) as queryType,
       max(case when OCV_VNAME_common like '%resourceName' then OCV_VALUE end) as resourceName,
       max(case when OCV_VNAME_common like '%saveTo' then OCV_VALUE end) as saveTo,
       max(case when OCV_VNAME_common like '%useArray' then OCV_VALUE end) as useArray
from t
group by OH_IDNR,
         regexp_replace(OCV_VNAME, '^(.*)(code_0|queryType|resourceName|saveTo|useArray)$', '\1');
1 голос
/ 17 февраля 2020

Вы можете выполнить условное агрегирование:

select
    oh_idnr,
    regexp_substr(ocv_vname, 'response_part_0_script_\d_') ocv_vname_common,
    max(case when ocv_vname like '%_code_0' then ocv_value end) code_0,
    max(case when ocv_vname like '%_queryType' then ocv_value end) queryType,
    max(case when ocv_vname like '%_resourceName' then ocv_value end) resourceName,
    max(case when ocv_vname like '%_saveTo' then ocv_value end) saveTo,
    max(case when ocv_vname like '%_useArray' then ocv_value end) useArray
from mytable 
group by oh_idnr, regexp_substr(ocv_vname, 'response_part_0_script_\d_')

Демонстрация на DB Fiddle :

OH_IDNR | OCV_VNAME_COMMON          | CODE_0           | QUERYTYPE | RESOURCENAME         | SAVETO   | USEARRAY
------: | :------------------------ | :--------------- | :-------- | :------------------- | :------- | :-------
8420518 | response_part_0_script_0_ | $[*].id          | JSONPath  | profileIds#          | variable | TRUE    
8420518 | response_part_0_script_1_ | $[*].name        | JSONPath  | profileNames#        | variable | TRUE    
8420518 | response_part_0_script_2_ | $[*].environment | JSONPath  | profileEnvironments# | variable | TRUE    
8420518 | response_part_0_script_3_ | $[*].description | JSONPath  | profileDescriptions# | variable | TRUE    

Вы можете найти вначале более читабельно разбирать в подзапросе:

select
    oh_idnr,
    ocv_vname_common,
    max(case when ocv_var_name = 'code_0' then ocv_value end) code_0,
    max(case when ocv_var_name = 'queryType' then ocv_value end) queryType,
    max(case when ocv_var_name = 'resourceName' then ocv_value end) resourceName,
    max(case when ocv_var_name = 'saveTo' then ocv_value end) saveTo,
    max(case when ocv_var_name = 'useArray' then ocv_value end) useArray
from (
    select 
        oh_idnr,
        regexp_substr(ocv_vname, 'response_part_0_script_\d_') ocv_vname_common,
        regexp_replace(ocv_vname, 'response_part_0_script_\d_', '') ocv_var_name,
        ocv_value 
    from mytable
) t
group by oh_idnr, ocv_vname_common

Демонстрация на DB Fiddle

...