在 sql 中创建更多行的逻辑
logic to create more rows in sql
我有一个 table1,我想将其转换为预期的 table。
- 列的预期 table 逻辑:
- cal:来自table1的cal。 ID来自table1.
的ID
- 代码:根据我们在 f_a 中是否有值,用 lp 或 fp 填充,然后我们用 fp 作为代码创建一个新记录。与之相对应的是,我们检查 f_a 是否被填充,如果是,那么我们从 f_a 中获取该日期并放入相同 ID 的 Al 列中。我们还检查 f_pl 是否被填充,如果是,那么我们从中获取日期并将其放入 pl 列。
- 如果代码是 lp,那么我们检查是否填充了 l_a,然后我们获取该日期并将该代码和 ID 放入 Al 中的日期中。此外,我们检查是否填充了 lpl,如果是,则我们获取该日期并将其放入 pl。
我只是 SQL 的入门者,所以对于如何入门对我来说有点不知所措。请post一些解决方案。
table1:
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
更新:
我在table里面的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, cal, 'lp' as code, '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,
f_pl,
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, 'lp' as code, 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, cal, code;
我有一个 table1,我想将其转换为预期的 table。
- 列的预期 table 逻辑:
- cal:来自table1的cal。 ID来自table1. 的ID
- 代码:根据我们在 f_a 中是否有值,用 lp 或 fp 填充,然后我们用 fp 作为代码创建一个新记录。与之相对应的是,我们检查 f_a 是否被填充,如果是,那么我们从 f_a 中获取该日期并放入相同 ID 的 Al 列中。我们还检查 f_pl 是否被填充,如果是,那么我们从中获取日期并将其放入 pl 列。
- 如果代码是 lp,那么我们检查是否填充了 l_a,然后我们获取该日期并将该代码和 ID 放入 Al 中的日期中。此外,我们检查是否填充了 lpl,如果是,则我们获取该日期并将其放入 pl。
我只是 SQL 的入门者,所以对于如何入门对我来说有点不知所措。请post一些解决方案。
table1:
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
更新: 我在table里面的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, cal, 'lp' as code, '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,
f_pl,
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, 'lp' as code, 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, cal, code;