prod StartDate ENDdate
----------------------------
a 1789-04-01 1799-12-14
b 1797-03-04 1826-07-04
c 1801-03-04 1826-07-04
d 1809-03-04 1836-06-28
e 1817-03-04 1831-07-04
我正在尝试为上述情况找到解决方案,但无法获得逻辑。你能帮我这个忙吗?
问题是找到大多数产品处于活动状态的开始日期和结束日期。
例如:在上述样本数据中,在1817-03-04至1826-07-04之间,有将近4个产品(b,c,d,e)有效(3409天),而有1个产品(a)活跃于1789-04-01至1799-12-14之间。
结果应类似于
prod_count StartDate ENDdate
-----------------------------------
4 1817-03-04 1826-07-04
1 1789-04-01 1799-12-14
答案 0 :(得分:2)
测试表和数据:
create table startend ( prod, startdate, enddate )
as
select 'a', date'1789-04-01', date'1799-12-14' from dual union all
select 'b', date'1797-03-04', date'1826-07-04' from dual union all
select 'c', date'1801-03-04', date'1826-07-04' from dual union all
select 'd', date'1809-03-04', date'1836-06-28' from dual union all
select 'e', date'1817-03-04', date'1831-07-04' from dual ;
SQL> select * from startend;
PROD STARTDATE ENDDATE
a 01-APR-89 14-DEC-99
b 04-MAR-97 04-JUL-26
c 04-MAR-01 04-JUL-26
d 04-MAR-09 28-JUN-36
e 04-MAR-17 04-JUL-31
让我们假设我们需要查找/检查STARTDATE和ENDDATE的所有可能组合。我们可以在下面的内联视图中使用一个JOIN。在此查询中,rownum值已重命名为:ERA(稍后将用于GROUP BY)。
select
to_char( startdate, 'YYYY-MM-DD') start_
, to_char( enddate, 'YYYY-MM-DD') end_
, enddate - startdate as duration
, rownum as era
from (
select distinct
S1.startdate
, S2.enddate
from startend S1
join startend S2 on S1.startdate < S2.enddate
)
;
-- result
START_ END_ DURATION ERA
---------- ---------- ---------- ----------
1789-04-01 1836-06-28 17254 1
1789-04-01 1826-07-04 13607 2
1801-03-04 1831-07-04 11079 3
1809-03-04 1836-06-28 9978 4
1817-03-04 1836-06-28 7056 5
1817-03-04 1831-07-04 5235 6
1801-03-04 1826-07-04 9253 7
1809-03-04 1826-07-04 6331 8
1789-04-01 1831-07-04 15433 9
1797-03-04 1799-12-14 1015 10
1797-03-04 1826-07-04 10713 11
1797-03-04 1831-07-04 12539 12
1817-03-04 1826-07-04 3409 13
1789-04-01 1799-12-14 3909 14
1797-03-04 1836-06-28 14360 15
1801-03-04 1836-06-28 12900 16
1809-03-04 1831-07-04 8157 17
17 rows selected.
您所需的条件似乎如下(请参阅WHERE子句):
-- test dates: from your question
select prod
from startend
where startdate <= date'1817-03-04' and startdate < date'1826-07-04'
and enddate > date'1817-03-04' and enddate >= date'1826-07-04'
;
-- result
b
c
d
e
最后一步:结合前两个查询的想法,例如(Oracle 11g):
select count(*) as "prod_count"
, to_char( E.startdate, 'YYYY-MM-DD' ) as "StartDate"
, to_char( E.enddate, 'YYYY-MM-DD' ) as "EndDate"
from
(
select startdate, enddate, rownum as era
from
(
select distinct
S1.startdate
, S2.enddate
from startend S1 join startend S2 on S1.startdate < S2.enddate
)
) E
join
(
select distinct prod, startdate, enddate from startend
) P
on
( P.startdate <= E.startdate and P.startdate < E.enddate )
and ( P.enddate > E.startdate and P.enddate >= E.enddate )
--
group by era, E.startdate, E.enddate
order by 2, 3
;
结果
prod_count StartDate EndDate
---------- ---------- ----------
1 1789-04-01 1799-12-14
2 1797-03-04 1799-12-14
1 1797-03-04 1826-07-04
2 1801-03-04 1826-07-04
3 1809-03-04 1826-07-04
1 1809-03-04 1831-07-04
1 1809-03-04 1836-06-28
4 1817-03-04 1826-07-04
2 1817-03-04 1831-07-04
1 1817-03-04 1836-06-28
10 rows selected.
另请参见:dbfiddle here。在使用Oracle 12c(或18c)时,可以使用CROSS APPLY(而不是JOIN ... ON ...)
答案 1 :(得分:0)
1)
5
-可以使用相同的StartDate和ENDdate值。
2)另一个想法可以是:
messagingTemplate.convertAndSend(message.getExchange(), message.getRoutingKey(), message.getPayload());
-它在相同的时间段内工作。
对不起,我没有Oracle实例访问权限,因此没有经过事先测试就可以直接使用它,因此可能会有一些不准确性。