试图根据表A中的数据找到一种有效的方法来实现下表B中的结果。假设一个表A中有数百万个这样的记录,是否存在这样做的有效方式(即资源不足)?请注意,ID 1的结束日期为12/31/2199(不是拼写错误),我们仅列出2016年9月至2016年12月期间每个ID的收入。另请注意,ID 3在2016年11月有两个收入,600表示11月收入(因为这是ID在2016年11月底的收入)。至于在2016年11月开始的ID,由于它们在11月之前不存在,它们的行将在9月16日和10月16日丢失。
表A:
ID INCOME EFFECTIVE_DATE END_DATE
1 700 07/01/2016 12/31/2199
2 500 08/20/2016 12/31/2017
3 600 11/11/2016 02/28/2017
3 100 09/01/2016 11/10/2016
4 400 11/21/2016 12/31/2016
表B(预期结果):
ID INCOME MONTH
1 700 12/2016
1 700 11/2016
1 700 10/2016
1 700 09/2016
2 500 12/2016
2 500 11/2016
2 500 10/2016
2 500 09/2016
3 600 12/2016
3 600 11/2016
3 100 10/2016
3 100 09/2016
4 400 12/2016
4 400 11/2016
已解决我使用了下面@mathguy提供的答案,它就像一个魅力 - 在这个过程中学到了新的东西:pivot和unpivot。还要感谢@MTO(以及其他所有人)花时间提供帮助。
答案 0 :(得分:2)
这是一个解决方案,它只使用基表中的每一行,并且不需要连接,分组等。它使用自Oracle 11.1以来可用的unpivot
操作,这不是一项昂贵的操作
with
table_a ( id, income, effective_date, end_date ) as (
select 1, 700, date '2016-07-01', date '2199-12-31' from dual union all
select 2, 500, date '2016-08-20', date '2017-12-31' from dual union all
select 3, 600, date '2016-11-11', date '2017-02-28' from dual union all
select 3, 100, date '2016-09-01', date '2016-11-10' from dual union all
select 4, 400, date '2016-11-21', date '2016-12-31' from dual
)
-- end of test data (not part of the solution): SQL query begins BELOW THIS LINE
select id, income, mth
from (
select id,
case when date '2016-09-30' between effective_date and end_date
then income end as sep16,
case when date '2016-10-31' between effective_date and end_date
then income end as oct16,
case when date '2016-11-30' between effective_date and end_date
then income end as nov16,
case when date '2016-12-31' between effective_date and end_date
then income end as dec16
from table_a
)
unpivot ( income for mth in ( sep16 as '09/2016', oct16 as '10/2016', nov16 as '11/2016',
dec16 as '12/2016' )
)
order by id, mth desc
;
<强>输出强>:
ID INCOME MTH
-- ------ -------
1 700 12/2016
1 700 11/2016
1 700 10/2016
1 700 09/2016
2 500 12/2016
2 500 11/2016
2 500 10/2016
2 500 09/2016
3 600 12/2016
3 600 11/2016
3 100 10/2016
3 100 09/2016
4 400 12/2016
4 400 11/2016
14 rows selected.