Запрос Oracle для получения результата набора реляционных данных из многомерной таблицы - PullRequest
1 голос
/ 30 июня 2019

У меня есть таблица данных, которая является многомерной / нереляционной.Я пытаюсь написать запрос, который динамически записывает все имена столбцов и упорядочивает данные реляционно.

Пример представляет собой простую таблицу с 5 книгами.Столбцы показывают размеры страниц в книге.Набор результатов, который я ищу, будет иметь 3 столбца: BOOK_ID, PAGE, PAGE_SIZE.Я включил простой код для построения таблицы.

Мне удалось обойтись с помощью запроса объединения, но это нецелесообразно для огромного количества столбцов.Набор данных содержит почти 100 столбцов.

CREATE TABLE 
    BOOK_PAGE_SIZE 
        ( 
          BOOK_ID VARCHAR2(5)
        , SIZE_PAGE_1 NUMBER 
        , SIZE_PAGE_2 NUMBER
        , SIZE_PAGE_3 NUMBER
        , SIZE_PAGE_4 NUMBER
        , SIZE_PAGE_5 NUMBER
        );


INSERT INTO BOOK_PAGE_SIZE  VALUES ('T7001',10,35,0,0,0);
INSERT INTO BOOK_PAGE_SIZE  VALUES ('T7002',45,84,78,0,0);
INSERT INTO BOOK_PAGE_SIZE  VALUES ('T7003',28,65,12,32,0);
INSERT INTO BOOK_PAGE_SIZE  VALUES ('T7004',94,74,69,21,76);
INSERT INTO BOOK_PAGE_SIZE  VALUES ('T7005',91,23,14,61,46);

РЕЗУЛЬТАТ:

  BOOK_ID  PAGE_NUMBER  PAGE_SIZE
   T70001     Page 1       10
   T70001     Page 2       35
   T70001     Page 3        0
   T70001     Page 4        0
   T70001     Page 5        0
   T70002     Page 1       45
   T70002     Page 2       84
   T70002     Page 3       78
   T70002     Page 4        0
   T70002     Page 5        0
   T70003     Page 1       28
   T70003     Page 2       65
   T70003     Page 3       12
   T70003     Page 4       32
   T70003     Page 5        0
   T70004     Page 1       94
   T70004     Page 2       74
   T70004     Page 3       69
   T70004     Page 4       21
   T70004     Page 5       76
   T70005     Page 1       91
   T70005     Page 2       23
   T70005     Page 3       14
   T70005     Page 4       61
   T70005     Page 5       46

Ответы [ 3 ]

3 голосов
/ 30 июня 2019

Вы можете использовать unpivot:

select *
  from  
  (
   with book_page_size(book_id,size_page_1,size_page_2,size_page_3,size_page_4,size_page_5) as
   (
    select 'T7001', 10, 35,  0,  0,  0 from dual union all
    select 'T7002', 45, 84, 78,  0,  0 from dual union all
    select 'T7003', 28, 65, 12, 32,  0 from dual union all
    select 'T7004', 94, 74, 69, 21, 76 from dual union all
    select 'T7005', 91, 23, 14, 61, 46 from dual 
   )
   select *
     from book_page_size a
  ) 
  unpivot (page_size for page_number in (size_page_1 as 'Page 1',
                                         size_page_2 as 'Page 2',
                                         size_page_3 as 'Page 3',
                                         size_page_4 as 'Page 4',
                                         size_page_5 as 'Page 5'))
  order by book_id, page_number;

Демо

1 голос
/ 30 июня 2019

Как ответил Барбарос Ожан, UNPIVOT выглядит хорошим инструментом для этой работы и требует меньше кода.Кроме того, вы можете использовать запрос SQL для создания запроса, который вы хотите!Я делаю это часто.Я создал таблицу с 20 столбцами SIZE_PAGE * для демонстрации.

select 'select book_id, ''Page ''||page_number as page_number, page_size from book_page_size' txt from dual union all
select 'unpivot (' from dual union all
select '  page_size for page_number in (' from dual union all
select '    ' || column_name || ' as ' || replace(column_name, 'SIZE_PAGE_') ||
case when lead(column_id) over(order by column_id) is not null
  then ','
end
from user_tab_columns
where table_name = 'BOOK_PAGE_SIZE'
and column_name != 'BOOK_ID'
union all
select ')) u' from dual union all
select 'order by u.book_id, u.page_number' from dual;

Запустив это, я получаю следующий запрос:

select book_id, 'Page '||page_number as page_number, page_size from book_page_size
unpivot (
  page_size for page_number in (
    SIZE_PAGE_1 as 1,
    SIZE_PAGE_2 as 2,
    SIZE_PAGE_3 as 3,
    SIZE_PAGE_4 as 4,
    SIZE_PAGE_5 as 5,
    SIZE_PAGE_6 as 6,
    SIZE_PAGE_7 as 7,
    SIZE_PAGE_8 as 8,
    SIZE_PAGE_9 as 9,
    SIZE_PAGE_10 as 10,
    SIZE_PAGE_11 as 11,
    SIZE_PAGE_12 as 12,
    SIZE_PAGE_13 as 13,
    SIZE_PAGE_14 as 14,
    SIZE_PAGE_15 as 15,
    SIZE_PAGE_16 as 16,
    SIZE_PAGE_17 as 17,
    SIZE_PAGE_18 as 18,
    SIZE_PAGE_19 as 19,
    SIZE_PAGE_20 as 20
)) u
order by u.book_id, u.page_number

Когда я запускаю запрос, результат:

BOOK_ID   PAGE_NUMBER  PAGE_SIZE   
BK001     Page 1               1 
BK001     Page 2               2 
BK001     Page 3               3 
BK001     Page 4               4 
BK001     Page 5               5 
BK001     Page 6               6 
BK001     Page 7               7 
BK001     Page 8               8 
BK001     Page 9               9 
BK001     Page 10             10 
BK001     Page 11             11 
BK001     Page 12             12 
BK001     Page 13             13 
BK001     Page 14             14 
BK001     Page 15             15 
BK001     Page 16             16 
BK001     Page 17             17 
BK001     Page 18             18 
BK001     Page 19             19 
BK001     Page 20             20 
0 голосов
/ 30 июня 2019

Вы можете использовать какой-нибудь союз все

    select  BOOK_ID,  'Page 1'  PAGE_NUMBER, SIZE_PAGE_1 PAGE_SIZE
    from  BOOK_PAGE_SIZE 
    union all  
    select  BOOK_ID,  'Page 2'  , SIZE_PAGE_2
    from  BOOK_PAGE_SIZE 
    union all  
    select  BOOK_ID,  'Page 3'  , SIZE_PAGE_3
    from  BOOK_PAGE_SIZE 
    union all  
    select  BOOK_ID,  'Page 4'  , SIZE_PAGE_4
    from  BOOK_PAGE_SIZE 
    union all  
    select  BOOK_ID,  'Page 5'  , SIZE_PAGE_5
    from  BOOK_PAGE_SIZE 
    order by BOOK_ID PAGE_NUMBER, PAGE_SIZE

но вы не должны использовать набор столбцов, вы должны нормализовать вашу схему

...