sql - 如何将此混合行/列表转换为所需的输出。(Oracle SQL/发行版:Ora12c)
问题描述
我有这个 Excel 输入文件被远程传递,并试图将它导入到这个最终结果中,但没有任何运气。任何帮助/指针将不胜感激。到目前为止,我已经尝试过 Oracle LEAD 函数来获取前 6 行的数据(如果在这种情况下这是正确的术语),其余的有问题。
所以我的传入数据采用这种格式(我在第 4 列的最后添加了行/行号,以使我的 LEAD 函数工作)。
+-----------+--------------+-------+------+
| Col1 | Col2 | Col3 | Col4 |
+-----------+--------------+-------+------+
| FYear | 2019 | | 1 |
| Office | ABC | | 2 |
| Org | xyz | | 3 |
| Acct | 11122233 | | 4 |
| SubAcct | 555666 | | 5 |
| Status | C | | 6 |
| 1000 | blahblahblah | $1000 | 7 |
| 1001 | blahblahxxyy | $999 | 8 |
| 1029 | blahblahxxyy | $7676 | 9 |
| ..... | .......... | ..... | .. |
| FYear | 2019 | | 55 |
| Office | EFG | | 56 |
| Org | xyz | | 57 |
| Acct | 11122233 | | 58 |
| SubAcct | 555888 | | 59 |
| Status | C | | 60 |
| 1000 | blahblahblah | $4440 | 61 |
| 1001 | blahblahxxyy | $3875 | 62 |
| 1029 | blahblahxxyy | $5029 | 63 |
| ......... | ...... | .... | ... |
+-----------+--------------+-------+------+
我试图让它成为这种输出格式。
+------+------+------+--------+--------+------+------+--------------+-------+
| Col1 | Col2 | Col3 | Col4 | Col5 | Col6 | Col7 | Col8 | Col9 |
+------+------+------+--------+--------+------+------+--------------+-------+
| 2019 | ABC | xyz | 112233 | 555666 | C | 1000 | blahblahblah | $1000 |
| 2019 | ABC | xyz | 112233 | 555666 | C | 1001 | blahblahxxyy | $999 |
| 2019 | ABC | xyz | 112233 | 555666 | C | 1029 | blahblahxxyy | $7676 |
| ... | ... | ... | ... | ... | . | ... | ... | ... |
| 2019 | EFG | xyz | 112233 | 555888 | C | 1000 | blahblahblah | $4440 |
| 2019 | EFG | xyz | 112233 | 555888 | C | 1001 | blahblahxxyy | $3875 |
| 2019 | EFG | xyz | 112233 | 555888 | C | 1029 | blahblahxxyy | $5029 |
| ... | ... | ... | ... | ... | . | ... | ... | ... |
+------+------+------+--------+--------+------+------+--------------+-------+
从本质上讲,我需要将前 6 行(如果你愿意的话,标题行)变成水平/重复值,以用于在它们下面的行号。然后在 n 上重复逻辑,因为这些标题部分不断重复,行号表在它们下面。
任何指针/帮助表示赞赏!
Ps:-这是我迄今为止尝试过/想出的。
select (CASE WHEN Col1 = 'FYear' THEN Col2 END) New_Col1,
LEAD((CASE WHEN Col1 = 'Office' THEN Col2 END)) OVER (ORDER BY Col4) New_Col2,
LEAD((CASE WHEN Col1 = 'Org' THEN Col2 END),2,0) OVER (ORDER BY Col4) New_Col3,
LEAD((CASE WHEN Col1 = 'Acct' THEN Col2 END),3,0) OVER (ORDER BY Col4) New_Col4,
LEAD((CASE WHEN Col1 = 'SubAcct' THEN Col2 END),4,0) OVER (ORDER BY Col4) New_Col5,
LEAD((CASE WHEN Col1 = 'Status' THEN Col2 END),5,0) OVER (ORDER BY Col4) New_Col6
from demo_table
where col4 <7;
解决方案
我赞同行没有在数据库中排序的评论。此外,您没有指定段是否可以超过 9 行。
我有一个适用于任意数量行 pr 段的解决方案,如果订单以某种方式保留,它需要每个段以 col1 中的“FYear”开头,并保留订单,但不关心如果标题行之后正好有三行。
设置:
create table testtbl
(
col1 varchar2(100)
,col2 varchar2(100)
,col3 varchar2(100)
,col4 int
)
insert into testtbl values ('FYear' ,2019,'',1);
insert into testtbl values ('Office' ,'ABC','',2);
insert into testtbl values ('Org' ,'xyz','',3);
insert into testtbl values ('Acct' ,11122233,'',4);
insert into testtbl values ('SubAcct',555666,'',5);
insert into testtbl values ('Status' ,'C','',6);
insert into testtbl values (1000 ,'blahblahblah',1000,7);
insert into testtbl values (1001 ,'blahblahxxyy',999,8);
insert into testtbl values (1029 ,'blahblahxxyy',7676,9);
insert into testtbl values ('FYear' ,2019,'',10);
insert into testtbl values ('Office' ,'EFG','',11);
insert into testtbl values ('Org' ,'xyz','',12);
insert into testtbl values ('Acct' ,11122233,'',13);
insert into testtbl values ('SubAcct',555888,'',14);
insert into testtbl values ('Status' ,'C','',15);
insert into testtbl values (1000 ,'blahblahblah',4440,16);
insert into testtbl values (1001 ,'blahblahxxyy',3875,17);
insert into testtbl values (1029 ,'blahblahxxyy',5029,18);
解决方案:
我首先创建一个跨越序列中所有行的 grp,然后在该组中找到标题值并将它们放在前 6 列中。然后我将原来的 3 列添加为 col7-9,最后过滤掉包含标题的行。
select
col1,col2,col3,col4,col5,col6,col7,col8,col9
from
(
select
max(case when col1='FYear' then Col2 else '' end) over (partition by grp) Col1
,max(case when col1='Office' then Col2 else '' end) over (partition by grp) Col2
,max(case when col1='Org' then Col2 else '' end) over (partition by grp) Col3
,max(case when col1='Acct' then Col2 else '' end) over (partition by grp) Col4
,max(case when col1='SubAcct' then Col2 else '' end) over (partition by grp) Col5
,max(case when col1='Status' then Col2 else '' end) over (partition by grp) Col6
, col1 col7
, col2 col8
, col3 col9
from
(
select
col1,col2,col3,col4
,sum(case when col1='FYear' then 1 else 0 end ) over (order by col4) grp
from testtbl t
) a
) b
where col7 not in('FYear','Office','Org','Acct','SubAcct','Status' )
推荐阅读
- google-sheets - Arrayformula 比较两列并跳过空白单元格
- node.js - 如何使用 amqplib 在没有 IP 地址的情况下本地访问 RabbitMQ?
- groovy - 在更新时根据从另一个字段中的选择清除选择自定义字段
- nginx - 如果 nginx.conf 中没有 mime.types 会发生什么?
- vue.js - Vuejs 仅在一个 vue 组件中创建 websocket 连接
- python-3.x - 在 python 轮中仅包含 *.pyc 文件
- azure-devops - Azure DevOps,资源组的默认角色分配是什么?
- ns-3 - 使用 NS3 拓扑生成器时出现问题
- python-3.x - 如何连接matplotlib散点图的某个特定节点?
- java - 选择带有 thymeleaf 和 th:each 的行