我有一个多维/非关系数据表。我正在尝试编写一个查询,该查询可以动态写出所有列名并按关系排列数据。
该示例是一个简单的表格,其中显示了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
答案 0 :(得分:3)
您可以使用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 :(得分:1)
正如BarbarosÖzhan回答的那样,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
答案 2 :(得分:0)
您可以全部使用一些联合
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
但您不应使用列集,而应规范化架构