如何解决在sql中创建更多行的逻辑
我有一个table1,想要转换为预期的表。
- 列的预期表逻辑:
- cal:来自table1的cal。 ID来自table1的ID。
- 代码:根据是否在f_a中有一个值,使用lp或fp填充该代码,然后创建一个以fp作为代码的新记录。与此相对应,我们检查是否填充了f_a,如果是,则从f_a中获取该日期,并在Al列中输入相同的ID。我们还要检查是否填充了f_pl,如果是,则从中获取日期并将其放在pl列中。
- 如果代码为lp,则我们检查是否填充了l_a,然后将该日期和日期放入该代码和ID的Al中的日期。此外,我们检查是否填充了lpl,如果是,那么我们将该日期放入pl中。
我只是SQL的入门者,所以对如何启动它有点不知所措。请发布一些解决方案。
表1:
ID f_a l_a f_pl lpl cal
CNT 6/20/2018 6/28/2018 6/28/2018 1/31/2020
预期输出:
ID Cal code pl Al
CNT 1/31/2020 lp 6/28/2018 6/28/2018
CNT 1/31/2020 fp 6/20/2018
更新: 我在表中有更多ID,因此并不是CNT是唯一的ID。如果我使用unpivot,则所有ID都应遵循相同的逻辑。
解决方法
这是一个有关如何取消枢纽到行的问题。在Oracle中,我建议使用横向联接:
select t.id,t.cal,x.*
from mytable t
cross apply (
select 'lp' as code,t.lpl as pl,l_a as al from dual
union all
select 'fp',t.f_pl,t.f_a from dual
) x
此语法在Oracle 12.1及更高版本中可用。在早期版本中,您将使用union all
:
select id,cal,'lp' as code,lpl as pl,l_a as al from mytable
union all
select id,'fp',f_pl,f_a from mytable
,
您可以将UNPIVOT
用于多列,然后在日期上进行所需的检查:
with a as (
select
'CNT' as ID,date '2018-06-20' as f_a,date '2018-06-28' as l_a,cast(null as date) as f_pl,date '2018-06-28' as l_pl,date '2020-01-31' as cal
from dual
)
select *
from a
unpivot(
(pl,al) for code in ((l_pl,l_a) as 'lp',(f_pl,f_a) as 'fp')
) up
ID | CAL | CODE | PL | AL
CNT | 31-JAN-07 | lp | 28-JUN-18 | 28-JUN-18
CNT | 31-JAN-07 | fp | | 20-JUN-18
,
请尝试使用非版本依赖的脚本:
-- Here we select columns foom source table. Please change the names if they are different
with r as (
select
ID,f_a,l_a,lpl,-- Here not sure if example is wrong or no underscore in column deffinition
cal
from table_1 -- Please put real table name here
)
select * from (
select r.id,r.cal,r.l_pl as pl,l_a as ai
from r
where r.l_a is not null
union all
select r1.id,r1.cal,'pl',r1.f_pl,r1.f_a
from r r1
where r1.f_a is not null
)
order by id,code;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。