как разбить данные в снежинке и поместить их в соответствующие столбцы - PullRequest
1 голос
/ 06 мая 2020

ПРИМЕР:

id  core           primary         secondary
101 4355|6755     4355|7866 
102 8566|6755      8566              8566
```````````````````````````````````````````````````````````````````````````````

I need to split the data into another table. One with only codes and indicators. All the codes should be in one column under codes and their respective codes as an indicator in other columns as below:
``````````````````````````````````````````````````````````````````````````

id      codes       core_ind        primary_ind secondary_ind
101     4355        Y                   Y   
101     6755        Y           
101     7866                            Y   
102     8566        Y                   Y           Y
102     6755        Y           

Я могу разделить столбцы с помощью бокового, но не знаю, как разместить индикаторы в соответствующих столбцах. Вы можете что-нибудь предложить? Ниже приведен код, который я использовал для разделения. Используя этот код, я могу поместить все коды и идентификаторы в соответствующие столбцы. Теперь мне нужно поставить индикаторы, о которых я говорил выше

SELECT id, c.value::varchar AS codes 
FROM table
   ,lateral flatten (input => split(core, '|')) c
UNION ALL 
SELECT id, d.value::varchar AS codes 
FROM  table 
   ,lateral flatten (input => split(primary, '|')) d
UNION ALL 
SELECT id, e.value::varchar AS codes 
FROM table
    ,lateral flatten (input => split(secondary, '|')) e

Заранее спасибо !!

1 Ответ

1 голос
/ 06 мая 2020

не то, чтобы я был большим фанатом профсоюзов, пока оставив их в покое, его можно заставить работать следующим образом:

with data as (
    select * from values (101, '4355|6755', '4355|7866', NULL),
                         (102, '8566|6755', '8566'     , 8566)
         v(id, core, primary, secondary)
), exploded as (      
    SELECT id, 'c' as type, c.value::varchar AS codes 
    FROM data
       ,lateral flatten (input => split(core, '|')) c
    UNION ALL 
    SELECT id, 'p' as type, d.value::varchar AS codes 
    FROM  data 
       ,lateral flatten (input => split(primary, '|')) d
    UNION ALL 
    SELECT id, 's' as type, e.value::varchar AS codes 
    FROM data
        ,lateral flatten (input => split(secondary, '|')) e
)
select id
    ,codes
    ,iff(sum(iff(type='c',1,0))>0,'Y','') as core_ind
    ,iff(sum(iff(type='p',1,0))>0,'Y','') as primary_ind
    ,iff(sum(iff(type='s',1,0))>0,'Y','') as secondary_ind
from exploded
group by 1,2
order by 1,2;

это дает:

ID  CODES   CORE_IND   PRIMARY_IND   SECONDARY_IND
101 4355    Y          Y    
101 6755    Y       
101 7866               Y    
102 6755    Y       
102 8566    Y          Y            Y

так что это также можно сделать с помощью UNPIVOT, а затем FLATTEN, не намного лучше:

with data as (
   select * from values (101, '4355|6755', '4355|7866', NULL),
                         (102, '8566|6755', '8566'     , '8566')
         v(id, data_a, data_b, data_c)
), unpivoted as (
    select * 
    from data unpivot(code for type in (data_a, data_b, data_c))
), flattened as (
    select id, type, f.value as codes
    from unpivoted
        ,lateral flatten (input => split(code, '|')) f
)
select id
    ,codes
    ,iff(sum(iff(type='DATA_A',1,0))>0,'Y','') as core_ind
    ,iff(sum(iff(type='DATA_B',1,0))>0,'Y','') as primary_ind
    ,iff(sum(iff(type='DATA_C',1,0))>0,'Y','') as secondary_ind
from flattened
group by 1,2
order by 1,2;
...