问题描述
嗨,汤姆,
我有下表
像这样的数据-
我正在寻找以下结果:
由于所有3个产品在31-7月-17之前都处于活动状态,因此第一行应将所有指示器显示为 “y”。产品 “B” 和 “c” 的下一行应显示第一行的START_DT = END_DT 1的指示器 “y”,直到产品B的结束日期为止,因为两者都在31-8月-17之前处于活动状态,依此类推...
我尝试使用以下枢轴解决方案,但没有运气。
如果你提供一个动态的解决方案,将是非常感激的。
我有下表
CREATE TABLE PRDCT (ID NUMBER(10,0), PRDCT_CD VARCHAR2(1), START_DT DATE, END_DT DATE);
像这样的数据-
Insert Into PRDCT Values (1,'A',to_date('01-May-2017'),to_date('31-Jul-2017'))
Insert Into PRDCT Values (1,'B',to_date('01-May-2017'),to_date('31-Aug-2017'))
Insert Into PRDCT Values (1,'C',to_date('01-May-2017'),to_date('31-Dec-9999'))
SELECT * FROM PRDCT;
ID PRDCT_CD START_DT END_DT
--------------------------------------
1 A 01-MAY-17 31-JUL-17
1 B 01-MAY-17 31-Aug-17
1 C 01-May-17 31-Dec-99我正在寻找以下结果:
ID A_PRDCT_IND B_PRDCT_IND C_PRDCT_IND START_DT END_DT ----------------------------------------------------------------- 1 Y Y Y 01-MAY-17 31-JUL-17 1 N Y Y 01-Aug-17 31-Aug-17 1 N N Y 01-Sep-17 31-Dec-99
由于所有3个产品在31-7月-17之前都处于活动状态,因此第一行应将所有指示器显示为 “y”。产品 “B” 和 “c” 的下一行应显示第一行的START_DT = END_DT 1的指示器 “y”,直到产品B的结束日期为止,因为两者都在31-8月-17之前处于活动状态,依此类推...
我尝试使用以下枢轴解决方案,但没有运气。
SELECT ID,
CASE WHEN PRDCT_A = 'A' THEN 'Y' ELSE 'N' END AS A_PRDCT_IND,
CASE WHEN PRDCT_B = 'B' THEN 'Y' ELSE 'N' END AS B_PRDCT_IND,
CASE WHEN PRDCT_C = 'C' THEN 'Y' ELSE 'N' END AS C_PRDCT_IND,
START_DT,
END_DT
FROM PRDCT
PIVOT(MAX(PRDCT_CD) FOR PRDCT_CD IN ('A' PRDCT_A, 'B' PRDCT_B, 'C' PRDCT_C))如果你提供一个动态的解决方案,将是非常感激的。
专家解答
如果要显示所有可能的开始/结束周期以及每个周期中的活动代码,则可以:
-将开始/结束日期调整为单个日期列表。返回不同的日期
-通过返回日期和下一个日期 (带有潜在客户) 将其转换回开始/结束期间
-外部根据每个开始/结束周期中的产品将产品加入其中
-根据要显示的产品代码对行进行旋转。在聚合中,如果代码为非空,则返回 'Y'
-将空标志映射到N,并进行一些日期调整以获取要关闭的范围-关闭间隔
-将开始/结束日期调整为单个日期列表。返回不同的日期
-通过返回日期和下一个日期 (带有潜在客户) 将其转换回开始/结束期间
-外部根据每个开始/结束周期中的产品将产品加入其中
-根据要显示的产品代码对行进行旋转。在聚合中,如果代码为非空,则返回 'Y'
-将空标志映射到N,并进行一些日期调整以获取要关闭的范围-关闭间隔
with dates as (
select distinct dt
from prdct
unpivot (
dt for col in ( start_dt, end_dt )
)
), ranges as (
select dt start_dt,
lead ( dt ) over ( order by dt ) end_dt
from dates
), grps as (
select p.prdct_cd, p.id, d.start_dt, d.end_dt
from ranges d
left join prdct p
on p.start_dt <= d.start_dt
and p.end_dt >= d.end_dt
), rws as (
select g.*,
row_number () over (
partition by prdct_cd
order by start_dt
) rn
from grps g
where end_dt is not null
)
select id, start_dt + case when rn = 1 then 0 else 1 end start_dt, end_dt,
nvl ( a, 'N' ) a,
nvl ( b, 'N' ) b,
nvl ( c, 'N' ) c
from rws
pivot (
max ( case when prdct_cd is not null then 'Y' end )
for prdct_cd in ( 'A' a, 'B' b, 'C' c)
)
order by start_dt;
ID START_DT END_DT A B C
1 01-MAY-2017 00:00:00 31-JUL-2017 00:00:00 Y Y Y
1 01-AUG-2017 00:00:00 31-AUG-2017 00:00:00 N Y Y
1 01-SEP-2017 00:00:00 31-DEC-9999 00:00:00 N N Y 文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




