сводная таблица в sql oracle без агрегатов и константных выражений - PullRequest
1 голос
/ 07 мая 2019

Я хочу сделать своего рода сводную таблицу, но проблема в том, что столбцы, где выполняется сводная таблица, должны быть равны this_year и next_year.Я объясняю на примере.

with
  property(prop_name,  prop_val, planned_year) as (
    select 'BANKING',  'true' , '2018'   from dual union all
    select 'IT'     ,  'false', '2019'  from dual union all
    select 'TELECOM',  'false', '2019'  from dual union all
    select 'MEDIA'  ,  'false', '2020' from dual union all
    select 'APPLE'  ,  'true' , '2018'  from dual union all
    select 'MANGO'  ,  'true' , '2019'   from dual union all
    select 'ORANGE' ,  'false', '2019'   from dual union all
    select 'CARROT' ,  'false', '2019'  from dual union all
    select 'IT' ,  'true' , '2020'   from dual
  )
select *
from   property
pivot  (listagg(prop_val, ',') within group (order by null) 
        for planned_year in ('2019' this_year, '2020' next_year))
;

, что результат, который я хочу получить, за исключением того, что сводка должна быть в запланированном году этого года (то есть не в жестком коде 2019).Я попробовал это:

with
  property(prop_name,  prop_val, planned_year) as (
    select 'BANKING',  'true' , '2018'   from dual union all
    select 'IT'     ,  'false', '2019'  from dual union all
    select 'TELECOM',  'false', '2019'  from dual union all
    select 'MEDIA'  ,  'false', '2020' from dual union all
    select 'APPLE'  ,  'true' , '2018'  from dual union all
    select 'MANGO'  ,  'true' , '2019'   from dual union all
    select 'ORANGE' ,  'false', '2019'   from dual union all
    select 'CARROT' ,  'false', '2019'  from dual union all
    select 'IT' ,  'true' , '2020'   from dual
  )
select *
from   property
pivot  (listagg(prop_val, ',') within group (order by null) 
        for planned_year in (EXTRACT(YEAR FROM sysdate) this_year, EXTRACT(YEAR FROM sysdate)+1 next_year))

но потом я получаю ошибку:

"non-constant expression is not allowed for pivot|unpivot values"

Может кто-нибудь помочь сделать трюк?

1 Ответ

1 голос
/ 07 мая 2019

Я бы использовал listagg() с case здесь:

with
  property(prop_name,  prop_val, planned_year) as (
    select 'BANKING',  'true' , '2018' from dual union all
    select 'IT'     ,  'false', '2019' from dual union all
    select 'TELECOM',  'false', '2019' from dual union all
    select 'MEDIA'  ,  'false', '2020' from dual union all
    select 'APPLE'  ,  'true' , '2018' from dual union all
    select 'MANGO'  ,  'true' , '2019' from dual union all
    select 'ORANGE' ,  'false', '2019' from dual union all
    select 'CARROT' ,  'false', '2019' from dual union all
    select 'IT' ,      'true' , '2020' from dual)
select prop_name,
       listagg(case planned_year when to_char(sysdate, 'yyyy') then prop_val end, ',') 
         within group (order by null) this_year,
       listagg(case planned_year when to_char(add_months(sysdate, 12), 'yyyy') then prop_val end, ',') 
         within group (order by null) next_year
  from   property
  group by prop_name
  order by prop_name
...