connected by months

匿名 (未验证) 提交于 2019-12-03 01:06:02

问题:

Ok, I'm new using this connect by thing. But its always quite useful. I have this small problem you guys might be able to help me...

Given start month (say to_char(sysdate,'YYYYMM')) and end month (say, to_char(add_months(sysdate, 6),'YYYYMM')), want to get the list of months in between, in the same format.

Well, I want to use this into a partitions automation script. My best shot so far (pretty pitiful) yields invalid months e.g.'201034'... (and yea, I know, incredibly inefficient)

Follows the code:

SELECT id from     (select to_char(add_months(sysdate, 6),'YYYYMM') as tn_end, to_char(sysdate,'YYYYMM') as tn_start from dual) tabla,     (select * from         (Select Level as Id from dual connect by Level <= (Select to_char(add_months(sysdate, 1),'YYYYMM')from dual)) where id > to_char(sysdate,'YYYYMM')) t Where      t.Id between tabla.tn_start and tabla.tn_end 

how do I do to make this query return only valid months? Any tips?

cheers mates,

f.

回答1:

Best way might be to separate out the row generator from the date function. So generate a list from 0 to 6 and calculate months from that. If you want to pass the months in then do that in the with clause

with my_counter as (   Select Level-1 as id    from dual    connect by Level <= 7 )  select to_char(add_months(sysdate, id),'YYYYMM') from my_counter 

The example below will allow you to plug in the dates you require to work out the difference.

with my_counter as (   Select Level-1 as id    from dual    connect by level <= months_between(add_months(trunc(sysdate,'MM'), 6),        trunc(sysdate,'MM')) + 1 )  select to_char(add_months(trunc(sysdate, 'MM'), id),'YYYYMM') from my_counter 


回答2:

For generating dates and date ranges, I strongly suggest you create a permanent calendar table with one row for each day. Even if you keep 20 years in this table it will be small ~7500 rows. Having such a table lets you attach additional (potentially non-standard) information to a date. For example your company may use a 6-week reporting period which you cannot extract using TO_CHAR / TO_DATE. Pre-compute it and store it in this table.

Oh, and Oracle 11g has automatic partition management. If you are stuck with 10g, then this article may be of interest to you? Automatic Partition Management for Oracle 10g



回答3:

Try this:

with numbers as ( select level as n from dual   connect by level <= 7 ) select to_char (add_months (trunc(sysdate,'MM'), n-1), 'YYYYMM') id from numbers;  ID ------ 201012 201101 201102 201103 201104 201105 201106 


文章来源: connected by months
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!