Как динамически поворачивать строки - PullRequest
0 голосов
/ 23 сентября 2019

Мое рабочее место внедрило сервер Oracle Exadata для работы за нашей установкой SAS.Я нахожусь в процессе преобразования моего сценария SAS для запуска в этой среде Oracle с использованием SQL-кода.Кажется, я не могу придумать шарнир, который дает мне те же результаты, что и мой SAS "PROC TRANSPOSE"

Вот мой процесс из SAS

PROC TRANSPOSE DATA=WORK.ROW_LEVEL_DATA OUT=WORK.PIVOT_DATA (DROP= _NAME_ _LABEL_) PREFIX=ORDR;
  BY GROUPKEY;
  ID ORDR_NUM;
  VAR STRING_VAL;
RUN;

Мои данные настроены так, что каждыйSTRING_VAL нумеруется последовательно до 25. В настоящее время SAS поворачивается с помощью GROUPKEY и создает столбцы ORDR1, ORDR2, ORDR3 и т. Д. Вплоть до 25. Каждый STRING_VAL помещается в столбец с соответствующей нумерацией.

Этоэто результат, который я пытаюсь воссоздать, используя сквозной SQL.

GROUPKEY     ORDR1     ORDR2    ORDR3
123456       AAAAA     BBBBB    CCCCC
654645       AAAAA
759876       BBBBB     CCCCC

Любая помощь очень ценится!

РЕДАКТИРОВАТЬ: я обработал чуть более 1B записей с помощью SAS PROC, которыйпроизвел 98.6M транспонированных записей за 16 минут.Это приемлемое количество времени, но мне любопытно, есть ли лучший способ, использующий сквозной SQL.

1 Ответ

0 голосов
/ 24 сентября 2019

Вы можете сделать это в чистом SQL с чем-то вроде:

  • Используйте подзапрос, чтобы назначать номера для каждого заказа (row_number, если они уникальны, dens_rank, если они не являются), разбитый на группы
  • Поворот результата этого

, который дает:

create table t (
  groupkey integer,
  ordr_num varchar2(10)
);

insert into t values ( 123456, 'AAAAA' );
insert into t values ( 123456, 'BBBBB' );
insert into t values ( 123456, 'CCCCC' );
insert into t values ( 654645, 'AAAAA' );
insert into t values ( 759876, 'BBBBB' );
insert into t values ( 759876, 'CCCCC' );

with ranks as ( 
  select t.*, 
         dense_rank() over (
           partition by groupkey
           order by ordr_num
         ) rn
  from   t
)
  select * from ranks
  pivot (
    min ( ordr_num ) for rn in (
      1 ord1, 2 ord2, 3 ord3 -- etc. up to ord25
    )
  );

GROUPKEY    ORD1     ORD2      ORD3     
     123456 AAAAA    BBBBB     CCCCC     
     654645 AAAAA    <null>    <null>    
     759876 BBBBB    CCCCC     <null>  
...