Oracle查询以查找活动状态记录的开始和结束日期
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle查询以查找活动状态记录的开始和结束日期相关的知识,希望对你有一定的参考价值。
我有以下数据
+------+-----------+----------+-------+------------+
| 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来提取数据,因此性能也很重要。
有人可以帮我查询。
答案
你只需要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
另一答案
您似乎想要代码处于活动状态的时间段和当前状态。这是一个带有扭曲的基本聚合查询:
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()
函数。
另一答案
您可以使用类似的内容来获取开始和结束日期以及代码的当前状态。性能将取决于您将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
另一答案
要从您发布的样本数据中获得预期结果,您可以使用条件聚合。即如果状态有效,则仅将日期传递给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;
但我怀疑可能还有更多。如果活跃期多于一个怎么办?从最早的开始到最新的结束是否正确?如果有更多的句点匹配当前时间,哪一个确定当前状态怎么办?
以上是关于Oracle查询以查找活动状态记录的开始和结束日期的主要内容,如果未能解决你的问题,请参考以下文章
使用 Google BigQuery 上的开始/结束日期优化活动帐户查询