如何使用
拆分行Start Date : 02-OCT-2015
End Date : 31-DEC-2015
进入Oracle下面的行?
02-OCT-2015 31-OCT-2015
01-NOV-2015 30-NOV-2015
01-DEC-2015 31-DEC-2015
答案 0 :(得分:2)
SELECT SUBSTR(t.column_one, 1, INSTR(t.column_one, ' ')-1) AS col_one,
SUBSTR(t.column_one, INSTR(t.column_one, ' ')+1) AS col_two
FROM YOUR_TABLE t
<强>替代地强> 您可以使用正则表达式或子字符串函数。它在非常大的数据集上不会超快,但它可以完成工作。 as -
SELECT REGEXP_SUBSTR(t.column_one, '[^-]+', 1, 1) col_one,
REGEXP_SUBSTR(t.column_one, '[^-]+', 1, 2) col_two,
REGEXP_SUBSTR(t.column_one, '[^-]+', 1, 3) col_three,
FROM YOUR_TABLE t;
希望这会有所帮助。
答案 1 :(得分:2)
您可以使用以下方式完成所需的 DATE算术:
我们假设您有两个日期为开始和结束日期,以下查询将日期拆分为多行基于 MONTHS 。
SQL> WITH sample_data AS
2 (SELECT DATE '2015-10-02' Start_Date, DATE '2015-12-25' End_Date FROM DUAL)
3 -- end of sample_date to mock an actual table
4 SELECT CASE
5 WHEN start_date >= TRUNC(add_months(start_date,COLUMN_VALUE - 1),'MM')
6 THEN
7 TO_CHAR(start_date, 'YYYY-MM-DD')
8 ELSE
9 TO_CHAR(TRUNC(add_months(start_date,COLUMN_VALUE - 1),'MM'),'YYYY-MM-DD')
10 END new_start_date,
11 CASE
12 WHEN end_date <= last_day(TRUNC(add_months(start_date,COLUMN_VALUE - 1),'MM'))
13 THEN
14 TO_CHAR(end_date, 'YYYY-MM-DD')
15 ELSE
16 TO_CHAR(last_day(TRUNC(add_months(start_date,COLUMN_VALUE - 1),'MM')),
17 'YYYY-MM-DD')
18 END new_end_date
19 FROM sample_data,
20 TABLE(
21 CAST(
22 MULTISET
23 (SELECT LEVEL
24 FROM dual
25 CONNECT BY add_months(TRUNC(start_date,'MM'),LEVEL - 1) <= end_date
26 ) AS sys.OdciNumberList
27 )
28 )
29 ORDER BY column_value;
NEW_START_DATE NEW_END_DATE
-------------- ------------
2015-10-02 2015-10-31
2015-11-01 2015-11-30
2015-12-01 2015-12-25
查询的工作原理:
如果您应该使用 CONNECT BY子句了解行生成的工作原理,那么其余的就是简单的 DATE 算术。
TRUNC(date, 'MM')
给出了该月的第一天,在您的情况下,它将成为开始日期。
ADD_MONTHS(date, value)
会在值中指定的日期添加多个月。
LAST_DAY
给出了该月的最后一天,在您的情况下成为结束日期。
答案 2 :(得分:2)
所以你有你想要比较的范围:第一个范围是你感兴趣的时期(02-OCT-2015到31-DEC-2015),其他范围是几个月(01-OCT-2015到31-OCT) -2015)...是的,我知道你只想要02-OCT-2015,因为你的数据,但让我们做一件事......我们会到达那里!
你感兴趣的时期是从今天起的未来,所以你的答案需要展望未来。
这就是我的所作所为:
第1步: 列出月份,定义每个月的开始日期和结束日期: 这可以是表格或视图。我发表意见。
create view mymonths as
select
add_months(trunc(sysdate,'MONTH'), - rownum + 2) month_start,
add_months(trunc(sysdate,'MONTH'), - rownum + 3) -1 month_end,
from all_objects -- (or any table or view with enough rows)
where rownum < 13
-- today is 10-NOV-2015.
-- First row will month_start = 01-NOV-2015, minus 1 (the rownum) month = 01-OCT-2015 + 2 = 01-DEC-2015 and month_end = 31-DEC-2015 (find the next month_start, minus a day)
-- Next row = 01-NOV-2015 and 30-NOV-2015
-- Next row = 01-OCT-2015 and 31-OCT-2015...for 12 rows down
-- adjust the +3 and < 13 as necessary for the scope of your data
现在我们需要准备好我们的数据来加入我们的month_starts和month_ends:
如果列数据如下所示: 开课日期:02-OCT-2015结束日期:2015年12月31日 然后按照回复中的建议,我们可以使用substr来获取数据部分。
只是为了证明这个想法,让我们做一个这样的观点:
create view mydata as
select
to_date(substr(column,13,11),'dd-MON-yyyy') period_start,
to_date(substr(column,35,11),'dd-MON-yyyy') period_end
from MYTABLE
现在我们可以像这样“加入”:
Select
mydata.period_start, mydata.period_end,
mymonths.month_start, mymonths.month_end
From
mytable, mymonths
Where
-- this is tricky, but work it out: it's right...
mydata.period_start <= mymonths.month_end
and
mydata.period_end => my_months.month_start
- 看看结果,看看我们差不多了。但是你想要02-OCT-2015到2015年10月31日,或者让我们说句号开始或月开始 - 以最新和月末为准,我们会说句号为月末或月末,这是最早的:
Select
case
when mydata.period_start > mymonths.month_start
then mydata.period_start
else mymonths.month_start
end COL1,
case
when mydata.period_end < mymonths.month_end
then mydata.period_end
else mymonths.month_end
end COL2
From
mytable, mymonths
Where
-- this is tricky, but work it out: it's right...
mydata.period_start <= mymonths.month_end
and
mydata.period_end => my_months.month_start