现有数据:
A VALID_FROM VALID_TO
------------ ----------- -----------
ARN-1 01-APR-2015 31-DEC-9999
ARN-1 01-MAY-2015 31-DEC-9999
ARN-1 01-JUN-2015 31-DEC-9999
必需的输出:
A VALID_FROM VALID_TO
------------ ----------- -----------
ARN-1 01-APR-2015 30-APR-2015
ARN-1 01-MAY-2015 31-MAY-2015
ARN-1 01-JUN-2015 31-DEC-9999
如何编写Oracle PL / SQL过程来获取此输出?
答案 0 :(得分:1)
不需要 PL / SQL ,您可以在纯 SQL 中执行此操作。
您需要 LAST_DAY 功能才能获取该VALID_FROM
列中日期值的当月最后一天。 ROW_NUMBER 只是为了处理您需要魔法日期31-DEC-9999
的最大日期情况。
SQL> WITH sample_data AS(
2 SELECT 'ARN-1' A, DATE '2015-04-01' VALID_FROM, DATE '9999-12-31' VALID_TO FROM dual
3 UNION ALL
4 SELECT 'ARN-1' A, DATE '2015-05-01' VALID_FROM, DATE '9999-12-31' VALID_TO FROM dual
5 UNION ALL
6 SELECT 'ARN-1' A, DATE '2015-06-01' VALID_FROM, DATE '9999-12-31' VALID_TO FROM dual
7 UNION ALL
8 SELECT 'ARN-1' A, DATE '2015-07-01' VALID_FROM, DATE '9999-12-31' VALID_TO FROM dual
9 )
10 -- end of sample_data mimicking real table
11 SELECT a,
12 valid_from,
13 CASE
14 WHEN rn = 1
15 THEN DATE '9999-12-31'
16 ELSE valid_to
17 END valid_to
18 FROM
19 (SELECT A,
20 valid_from,
21 row_number() OVER(ORDER BY valid_from DESC) rn,
22 last_day(valid_from) valid_to
23 FROM sample_data
24 )
25 ORDER BY valid_from;
A VALID_FROM VALID_TO
----- ----------- -----------
ARN-1 01-APR-2015 30-APR-2015
ARN-1 01-MAY-2015 31-MAY-2015
ARN-1 01-JUN-2015 30-JUN-2015
ARN-1 01-JUL-2015 31-DEC-9999
SQL>
答案 1 :(得分:0)
你可能需要这样的东西:
insert into tableB
select A,
valid_from,
nvl(lead(valid_from) over (partition by a order by valid_from asc) -1, valid_to)
from tableA
这将插入第二个表中的所有行,为每一行评估有效性的结束(如果存在);如果它不存在,则使用该行上已存在的结束日期。
答案 2 :(得分:0)
Oracle安装程序:
CREATE TABLE table_name ( A, VALID_FROM, VALID_TO ) AS
SELECT 'ARN-1', DATE '2015-04-01', DATE '9999-12-31' FROM DUAL UNION ALL
SELECT 'ARN-1', DATE '2015-05-01', DATE '9999-12-31' FROM DUAL UNION ALL
SELECT 'ARN-1', DATE '2015-06-01', DATE '9999-12-31' FROM DUAL;
<强>更新强>:
UPDATE table_name t
SET valid_to = ( SELECT NVL( next_valid_from, valid_to )
FROM (
SELECT a,
valid_from,
LEAD( valid_from ) OVER ( PARTITION BY a ORDER BY valid_from )
- INTERVAL '1' SECOND -- Change to DAY if you prefer
AS next_valid_from,
valid_to
FROM table_name
) n
WHERE t.a = n.a
AND t.valid_from = n.valid_from
);
<强>输出强>:
SELECT * FROM table_name;
A VALID_FROM VALID_TO
----- --------------------- ---------------------
ARN-1 2015-04-01 00:00:00 2015-04-30 23:59:59
ARN-1 2015-05-01 00:00:00 2015-05-31 23:59:59
ARN-1 2015-06-01 00:00:00 9999-12-31 00:00:00