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