SQL - Oracle - сводная таблица с динамическими данными - PullRequest
0 голосов
/ 17 мая 2018

работает на базе данных Oracle, у меня есть следующая таблица 'GROUPS':

ID    NAME    LAYER    VALUE
1     A       L1       100
1     A       L2       200
1     A       L3       300
1     A       L4       400
1     A       L5       500
2     B       L1       111
2     B       L2       222
2     B       L3       333
2     B       L4       444
2     B       L5       555
2     B       L6       666
2     B       L7       777

**ID** - identifies the group.
**NAME** - group's name.
**LAYER** - a layer in the group ; a group consists of N layers.
**VALUE** - the value of a given layer in a given group.

данные в этой таблице представляют 2 элемента, различаемых по идентификатору (1 и 2).каждая группа содержит N слоев (для группы 1, L1-L5; для группы 2 L1-L7), каждый уровень имеет значение.

Я пытаюсь создать функциональность БД, которая будет поворачивать данные динамических слоев, чтобыкаждый слой станет столбцом, а его строки будут значениями для каждого уникального идентификатора (1,2) в таблице.

ID    NAME    L1    L2    L3    L4    L5    L6    L7    
1     A       100   200   300   400   500   
2     B       111   222   333   444   555   666   777

обратите внимание, что группы имеют разное количество слоев.

указанная функциональность может быть представлением, функцией или хранимой процедурой - чем угодно, пока она обрабатывается БД.

Большое спасибо за вашу помощь!

Нир

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

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

decalre
    sqlstr VARCHAR2(30000);
    cur SYS_REFCURSOR;
begin

    SELECT SELECT LISTAGG(''''||LAYER||''' AS '||layer, ',') WITHIN GROUP (ORDER BY LAYER)
    INTO sqlstr 
    FROM (SELECT LAYER FROM your_table GROUP BY LAYER);

    sqlstr := 'SELECT * FROM your_table PIVOT (MIN(VALUESS) FOR layers IN ('||sqlstr||'))';
    DBMS_OUTPUT.PUT_LINE(sqlstr);

    OPEN cur FOR sqlstr;
    ...

end;   
0 голосов
/ 17 мая 2018

Используя функцию Oracle PIVOT, вы можете сделать это следующим образом. Вы должны поместить список всех 30 значений в часть PIVOT, что я сделал до L7:

SQL> 
SQL> WITH cte_table(IDS, NAMES, LAYERS, VALUESS) as (
  2      SELECT 1, 'A', 'L1', 100 from dual union all
  3      SELECT 1, 'A', 'L2', 200 from dual union all
  4      SELECT 1, 'A', 'L3', 300 from dual union all
  5      SELECT 1, 'A', 'L4', 400 from dual union all
  6      SELECT 1, 'A', 'L5', 500 from dual union all
  7      SELECT 2, 'B', 'L1', 111 from dual union all
  8      SELECT 2, 'B', 'L2', 222 from dual union all
  9      SELECT 2, 'B', 'L3', 333 from dual union all
 10      SELECT 2, 'B', 'L4', 444 from dual union all
 11      SELECT 2, 'B', 'L5', 555 from dual union all
 12      SELECT 2, 'B', 'L6', 666 from dual union all
 13      SELECT 2, 'B', 'L7', 777 from dual)
 14  SELECT *
 15    FROM cte_table
 16   PIVOT (MIN(VALUESS) FOR layers IN ('L1' AS "L1", 'L2' AS "L2", 'L3' AS "L3", 'L4' AS "L4", 'L5' AS "L5", 'L6' AS "L6", 'L7' AS "L7")) --list goes here
 17  /

Выход:

       IDS NAMES         L1         L2         L3         L4         L5         L6         L7
---------- ----- ---------- ---------- ---------- ---------- ---------- ---------- ----------
         1 A            100        200        300        400        500            
         2 B            111        222        333        444        555        666        777
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...