我有以下数据
+------+-----------+----------+-------+------------+
| Code | StartDate | EndDate | Unit | CodeStatus |
+------+-----------+----------+-------+------------+
| 1001 | 20100101 | 20101231 | UnitA | Active |
| 1001 | 20110101 | 20151231 | UnitB | Active |
| 1001 | 20160101 | 21000101 | UnitB | Inactive |
| 1002 | 20160101 | 20181231 | UnitA | Active |
| 1002 | 20190101 | 21000101 | UnitA | Inactive |
| 1003 | 20140101 | 21000101 | UnitC | Active |
+------+-----------+----------+-------+------------+
如果我们看第一个代码(1001),则有两个活动记录,在输出中,我想要活动记录的最小开始日期和最高结束日期。如下
+------+-----------+----------+----------+
| Code | StartDate | EndDate | Status |
+------+-----------+----------+----------+
| 1001 | 20100101 | 20151231 | Inactive |
| 1002 | 20181231 | 20181231 | Inactive |
| 1003 | 20140101 | 21000101 | Active |
+------+-----------+----------+----------+
此表有大约一百万条记录,我使用api提取数据,因此性能也很重要。
有人可以帮助我进行查询。
答案 0 :(得分:1)
您似乎想要激活代码的时间段以及当前状态。这是一个基本的聚合查询,具有以下特点:
select code,
min(case when codestatus = 'Active' then start_date end) as active_start_date,
max(case when codestatus = 'Active' then end_date end) as active_end_date,
max(codestatus) keep (dense_rank first order by start_date desc) as current_code_status
from codes
group by code;
keep
是Oracle中的一个不错的功能,它本质上是一个聚合的first_value()
函数。
答案 1 :(得分:0)
您只需要max和min聚合函数
with cte as
(
select code,min(StartDate) as mStartDate,
max(EndDate) as mEndDate from table
where CodeStatus='Active' group by code
)
,cte1 as
(
select CodeStatus,code,
row_number()over(partition by code order by StartDate desc) rn
from table
) select cte.*,cte1.CodeStatus
from cte join cte1 on cte.code=cte1.code
where cte1.rn=1
答案 2 :(得分:0)
要从发布的样本数据中获得发布的预期结果,可以使用条件聚合。即如果状态为有效,则仅将日期传递到min()
或max()
。这样,您将获得最大和最小。要获取当前状态,请检查当前时间是在开始时间之后还是在开始时间之后以及结束时间之前。如果通过,则将状态传递给例如max()
。
SELECT code,
to_char(min(CASE
WHEN codestatus = 'Active' THEN
startdate
END), 'YYYYMMDD') startdate,
to_char(min(CASE
WHEN codestatus = 'Active' THEN
enddate
END), 'YYYYMMDD') enddate,
max(CASE
WHEN startdate <= sysdate
AND enddate > sysdate THEN
codestatus
END) status
FROM elbat
GROUP BY code
ORDER BY code;
但是我怀疑可能还有更多。如果活动期间多于一个期间怎么办?采用最早的开始和最新的开始是否正确?如果还有更多时间与当前时间匹配,那一个会决定当前状态怎么办?
答案 3 :(得分:0)
您可以使用类似的方法获取代码的开始日期和结束日期以及当前状态。性能取决于您将WITH部分中的选择限制为代码还是日期。
WITH CodeDates AS
(
select
code,
min(StartDate) startdate,
max(EndDate) enddate
from table
Group by code
)
Select c.code,
c.startdate
c.enddate,
t.codestatus
From CodeDates c
Join table t
on t.code = c.code
and t.enddate = c.enddate