Oracle 在添加日期时取消透视
Oracle unpivot while adding dates
我用一个简单的键链接了这两个表,一个包含项目名称及其开始日期,另一个包含计划,看起来像这样:
projects
ID NAME START_DATE
1 foo 01/01/2017
2 barr 01/02/2017
planning
PRJ M0 M1 M2
1 70 75 80
2 50 60 70
有人可以帮我加入这两个表以产生:
PRJ DATE PLAN
1 01/01/2017 70
1 01/02/2017 75
1 01/03/2017 80
2 01/02/2017 50
2 01/03/2017 60
2 01/04/2017 70
unpivot
好像在这里很有用,但我没有太多实践。
谢谢
考虑 运行 CTE 中的 UNPIVOT
。然后,在主查询中计算可用于将天数添加到 START_DATE 的行号。
此外,请考虑不要以具有 M*
列的宽格式存储数据,而是以原始值和指示符列的长格式存储数据。否则像下面这样的查询会很复杂。
WITH master AS
(SELECT *
FROM planning
UNPIVOT ("PLAN" FOR M_COLS IN (M0, M1, M2)) -- BUILD OUT LIST IN APP CODE
)
SELECT m.PRJ, p.START_DATE + m.row_num AS m."DATE", m."PLAN"
FROM projects p
INNER JOIN
(SELECT PRJ, "PLAN", ROW_NUMBER()
OVER (PARTITION BY PRJ ORDER BY PRJ) - 1 AS row_num
FROM master) AS m
ON p.ID = m.PRJ;
逆透视时,跟踪逆透视列的列可以是任何数据类型。在这种情况下,您可以将其设为 NUMBER
列,并且可以将值 0, 1, 2, ...
分配给列 M0, M1, M2, ...
- 这样您就可以直接使用它来调整开始日期。请参阅 UNPIVOT
子句的 IN
列表。
with
projects ( id, name, start_date ) as (
select 1, 'foo', to_date('01/01/2017', 'mm/dd/yyyy') from dual union all
select 2, 'bar', to_date('01/02/2017', 'mm/dd/yyyy') from dual
),
planning ( prj, m0, m1, m2 ) as (
select 1, 70, 75, 80 from dual union all
select 2, 50, 60, 70 from dual
)
-- End of simulated inputs (for testing only, not part of the solution).
-- SQL query begins BELOW THIS LINE.
select x.prj, p.start_date + x.col_num as start_date, x.plan
from projects p
join
( select prj, col_num, plan
from planning
unpivot ( plan for col_num in (m0 as 0, m1 as 1, m2 as 2) )
) x
on p.id = x.prj
order by prj, start_date -- If needed.
;
PRJ START_DATE PLAN
---------- ---------- ----------
1 01/01/2017 70
1 01/02/2017 75
1 01/03/2017 80
2 01/02/2017 50
2 01/03/2017 60
2 01/04/2017 70
我用一个简单的键链接了这两个表,一个包含项目名称及其开始日期,另一个包含计划,看起来像这样:
projects
ID NAME START_DATE
1 foo 01/01/2017
2 barr 01/02/2017
planning
PRJ M0 M1 M2
1 70 75 80
2 50 60 70
有人可以帮我加入这两个表以产生:
PRJ DATE PLAN
1 01/01/2017 70
1 01/02/2017 75
1 01/03/2017 80
2 01/02/2017 50
2 01/03/2017 60
2 01/04/2017 70
unpivot
好像在这里很有用,但我没有太多实践。
谢谢
考虑 运行 CTE 中的 UNPIVOT
。然后,在主查询中计算可用于将天数添加到 START_DATE 的行号。
此外,请考虑不要以具有 M*
列的宽格式存储数据,而是以原始值和指示符列的长格式存储数据。否则像下面这样的查询会很复杂。
WITH master AS
(SELECT *
FROM planning
UNPIVOT ("PLAN" FOR M_COLS IN (M0, M1, M2)) -- BUILD OUT LIST IN APP CODE
)
SELECT m.PRJ, p.START_DATE + m.row_num AS m."DATE", m."PLAN"
FROM projects p
INNER JOIN
(SELECT PRJ, "PLAN", ROW_NUMBER()
OVER (PARTITION BY PRJ ORDER BY PRJ) - 1 AS row_num
FROM master) AS m
ON p.ID = m.PRJ;
逆透视时,跟踪逆透视列的列可以是任何数据类型。在这种情况下,您可以将其设为 NUMBER
列,并且可以将值 0, 1, 2, ...
分配给列 M0, M1, M2, ...
- 这样您就可以直接使用它来调整开始日期。请参阅 UNPIVOT
子句的 IN
列表。
with
projects ( id, name, start_date ) as (
select 1, 'foo', to_date('01/01/2017', 'mm/dd/yyyy') from dual union all
select 2, 'bar', to_date('01/02/2017', 'mm/dd/yyyy') from dual
),
planning ( prj, m0, m1, m2 ) as (
select 1, 70, 75, 80 from dual union all
select 2, 50, 60, 70 from dual
)
-- End of simulated inputs (for testing only, not part of the solution).
-- SQL query begins BELOW THIS LINE.
select x.prj, p.start_date + x.col_num as start_date, x.plan
from projects p
join
( select prj, col_num, plan
from planning
unpivot ( plan for col_num in (m0 as 0, m1 as 1, m2 as 2) )
) x
on p.id = x.prj
order by prj, start_date -- If needed.
;
PRJ START_DATE PLAN
---------- ---------- ----------
1 01/01/2017 70
1 01/02/2017 75
1 01/03/2017 80
2 01/02/2017 50
2 01/03/2017 60
2 01/04/2017 70