我有以下要求。 我将数据存储在表格中,如下面的格式
ID Region State Status StatusDate
PCR1 1 GA Initial 25-Oct-14
PCR1 1 GA DM Review 27-Oct-14
PCR1 1 GA SD Review 29-Oct-14
PCR1 1 GA Final Review 31-Oct-14
PCR2 1 LA Initial 25-Sep-14
PCR2 1 LA DM Review 27-Sep-14
PCR2 1 LA SD Review 29-Sep-14
PCR2 1 LA Final Review 30-Sep-14
我想将上述数据转换为如下转换
ID Region State Status StartDate EndDate
PCR1 1 GA Initial 25-Oct-14 27-Oct-14
PCR1 1 GA DM Review 27-Oct-14 29-Oct-14
PCR1 1 GA SD Review 29-Oct-14 31-Oct-14
PCR1 1 GA Final Review 31-Oct-14 Current Date
PCR2 1 LA Initial 25-Sep-14 27-Sep-14
PCR2 1 LA DM Review 27-Sep-14 29-Sep-14
PCR2 1 LA SD Review 29-Sep-14 30-Sep-14
PCR2 1 LA Final Review 30-Sep-14 Current Date
如何实现这一目标。 EnDate根据下一个状态的状态数据到达。对于最终状态,结束日期为当前系统日期。请注意,上面显示的状态是指示性的,可能会有所不同。提前感谢您的回复
此致 阿尼尔
答案 0 :(得分:-1)
在任何支持窗口函数的dbms中,你可以非常简单地得到非常接近的东西。我在PostgreSQL中对此进行了测试,但它是标准的SQL,它也将在当前版本的SQL Server和Oracle中运行。 (对INSERT语句进行了微不足道的修改。)
create table test
(id char(4) not null,
region int not null,
state char(2) not null,
status varchar(15) not null,
statusdate date not null,
primary key (id, region, state, status)
);
insert into test values
('PCR1', 1, 'GA', 'Initial', '25-Oct-14'),
('PCR1', 1, 'GA', 'DM Review', '27-Oct-14'),
('PCR1', 1, 'GA', 'SD Review', '29-Oct-14'),
('PCR1', 1, 'GA', 'Final Review', '31-Oct-14'),
('PCR2', 1, 'LA', 'Initial', '25-Sep-14'),
('PCR2', 1, 'LA', 'DM Review', '27-Sep-14'),
('PCR2', 1, 'LA', 'SD Review', '29-Sep-14'),
('PCR2', 1, 'LA', 'Final Review', '30-Sep-14');
select id, region, state, status, statusdate,
lead(statusdate) over (partition by id order by statusdate) enddate
from test;
id region state status statusdate enddate -- PCR1 1 GA Initial 2014-10-25 2014-10-27 PCR1 1 GA DM Review 2014-10-27 2014-10-29 PCR1 1 GA SD Review 2014-10-29 2014-10-31 PCR1 1 GA Final Review 2014-10-31 PCR2 1 LA Initial 2014-09-25 2014-09-27 PCR2 1 LA DM Review 2014-09-27 2014-09-29 PCR2 1 LA SD Review 2014-09-29 2014-09-30 PCR2 1 LA Final Review 2014-09-30
你可以在输出中得到文字值'当前日期'而不是NULL,但如果我是你,我会认真思考。恕我直言,在应用程序代码中处理得更好。但是你可以这样重写SQL。
select id, region, state, status, statusdate,
coalesce(cast(enddate as varchar), 'Current date') enddate
from (select id, region, state, status, statusdate,
lead(statusdate) over (partition by id order by statusdate) enddate
from test
) x
id region state status statusdate enddate -- PCR1 1 GA Initial 2014-10-25 2014-10-27 PCR1 1 GA DM Review 2014-10-27 2014-10-29 PCR1 1 GA SD Review 2014-10-29 2014-10-31 PCR1 1 GA Final Review 2014-10-31 Current date PCR2 1 LA Initial 2014-09-25 2014-09-27 PCR2 1 LA DM Review 2014-09-27 2014-09-29 PCR2 1 LA SD Review 2014-09-29 2014-09-30 PCR2 1 LA Final Review 2014-09-30 Current date
我更喜欢这种输出的应用程序代码,因为在SQL中,“enddate”列不能作为日期列返回。它必须作为varchar列返回。