How to move data from partitioned table to another partitioned table - oracle

I have two monthly interval partitioned tables table1 and table2. Table1 is history table which holds historic data and table2 holds latest/live 6 months data. Every month I need to add or move the oldest partition from table2 to the history table table1.

Here is how to do it with no movement of data, just dictionary operations as Hermann has suggested.
T1 is my current 6 months, and T2 is history
SQL> create table t1
2 partition by range (x)
3 interval ( numtoyminterval(1,'MONTH') )
4 ( partition p1 values less than ( date '2021-01-01') )
5 as
6 select date '2021-01-01'+rownum x,
7 rownum y
8 from dual
9 connect by level <= 180;
Table created.
SQL>
SQL> create table t2
2 partition by range (x)
3 interval ( numtoyminterval(1,'MONTH') )
4 ( partition p1 values less than ( date '2015-01-01') )
5 as
6 select date '2021-01-01'-rownum x,
7 rownum y
8 from dual
9 connect by level <= 1000;
Table created.
SQL>
SQL> select partition_name, high_value
2 from user_tab_partitions
3 where table_name = 'T1';
PARTITION_NAME HIGH_VALUE
------------------------------ --------------------------------------------------------------------------------
P1 TO_DATE(' 2021-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22038 TO_DATE(' 2021-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22039 TO_DATE(' 2021-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22040 TO_DATE(' 2021-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22041 TO_DATE(' 2021-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22042 TO_DATE(' 2021-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22043 TO_DATE(' 2021-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
7 rows selected.
SQL>
SQL> select partition_name, high_value
2 from user_tab_partitions
3 where table_name = 'T2';
PARTITION_NAME HIGH_VALUE
------------------------------ --------------------------------------------------------------------------------
P1 TO_DATE(' 2015-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22044 TO_DATE(' 2021-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22045 TO_DATE(' 2020-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22046 TO_DATE(' 2020-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22047 TO_DATE(' 2020-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22048 TO_DATE(' 2020-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22049 TO_DATE(' 2020-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22050 TO_DATE(' 2020-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22051 TO_DATE(' 2020-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22052 TO_DATE(' 2020-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22053 TO_DATE(' 2020-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22054 TO_DATE(' 2020-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22055 TO_DATE(' 2020-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22056 TO_DATE(' 2020-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22057 TO_DATE(' 2019-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22058 TO_DATE(' 2019-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22059 TO_DATE(' 2019-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22060 TO_DATE(' 2019-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22061 TO_DATE(' 2019-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22062 TO_DATE(' 2019-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22063 TO_DATE(' 2019-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22064 TO_DATE(' 2019-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22065 TO_DATE(' 2019-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22066 TO_DATE(' 2019-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22067 TO_DATE(' 2019-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22068 TO_DATE(' 2019-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22069 TO_DATE(' 2018-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22070 TO_DATE(' 2018-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22071 TO_DATE(' 2018-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22072 TO_DATE(' 2018-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22073 TO_DATE(' 2018-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22074 TO_DATE(' 2018-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22075 TO_DATE(' 2018-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22076 TO_DATE(' 2018-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
34 rows selected.
To do a table exchange, you need to create a template table first, ie, you need something to exchange with
SQL>
SQL> create table exc
2 for exchange with table t1;
Table created.
Now I take the partition I want to remove from T1, and exchange it with EXC
SQL>
SQL> alter table t1 exchange partition for ( date '2021-01-15' ) with table exc;
Table altered.
Now I want to exchange it "into" T2, but I need a partition in T2 into which I can do the exchange. That partition does not exist yet, because it doesn't contain any of the 6 months in the current data. Thus we need to create an empty one. A simple trick to do that is the lock the non-existent partition, which will have the effect of creating one.
SQL>
SQL> lock table t2 partition for ( date '2021-01-15' ) in exclusive mode;
Table(s) Locked.
SQL>
SQL> select partition_name, high_value
2 from user_tab_partitions
3 where table_name = 'T2';
PARTITION_NAME HIGH_VALUE
------------------------------ --------------------------------------------------------------------------------
P1 TO_DATE(' 2015-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22044 TO_DATE(' 2021-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22045 TO_DATE(' 2020-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22046 TO_DATE(' 2020-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22047 TO_DATE(' 2020-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22048 TO_DATE(' 2020-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22049 TO_DATE(' 2020-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22050 TO_DATE(' 2020-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22051 TO_DATE(' 2020-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22052 TO_DATE(' 2020-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22053 TO_DATE(' 2020-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22054 TO_DATE(' 2020-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22055 TO_DATE(' 2020-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22056 TO_DATE(' 2020-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22057 TO_DATE(' 2019-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22058 TO_DATE(' 2019-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22059 TO_DATE(' 2019-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22060 TO_DATE(' 2019-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22061 TO_DATE(' 2019-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22062 TO_DATE(' 2019-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22063 TO_DATE(' 2019-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22064 TO_DATE(' 2019-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22065 TO_DATE(' 2019-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22066 TO_DATE(' 2019-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22067 TO_DATE(' 2019-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22068 TO_DATE(' 2019-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22069 TO_DATE(' 2018-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22070 TO_DATE(' 2018-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22071 TO_DATE(' 2018-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22072 TO_DATE(' 2018-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22073 TO_DATE(' 2018-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22074 TO_DATE(' 2018-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22075 TO_DATE(' 2018-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22076 TO_DATE(' 2018-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
SYS_P22077 TO_DATE(' 2021-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',
35 rows selected.
Notice that we gained a new partition (which is empty). Now I exchange the EXC table (which has 1 month of data) with the empty partition.
SQL>
SQL> alter table t2 exchange partition for ( date '2021-01-15' ) with table exc;
Table altered.
SQL>
and we are done. Notice that we never needed to reference any of the interval partitions by name, we just used the FOR option in order to avoid that.

Related

Possible to modify an existing partitioned Oracle table to utilize INTERVAL? [duplicate]

I have a table which is partitioned as below and has millions of rows of data. Table size is 120 GB.
PARTITION BY RANGE (Read_time) INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
Now I want to change to this partitioning strategy with existing data and future data. Table is inserted daily by job.
PARTITION BY RANGE (Read_time) INTERVAL(NUMTODSINTERVAL(1, 'DAY'))
I have 12 month partition (Oct'18 to Nov'19). I want partition to be converted to daywise.
For example: For Jul'19 partition, it should to be splitted to
01 Jul'19,
02 Jul'19
.......
31 Jul'19.
Data should also be moved to new partition
I tried split partition. New partition got created day wise , but rows didn't move to new partition.
To change for monthly interval to daily is a simple as
ALTER TABLE test SET INTERVAL (NUMTODSINTERVAL(1,'DAY'));
see the documentation for further details
Lets illustrate in on a small example
create table test
(dt date)
PARTITION BY RANGE (dt)
INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
(
PARTITION part_01 values LESS THAN (TO_DATE('01-01-2019','DD-MM-YYYY'))
);
insert into test (dt)
select date'2019-01-01' + rownum dt from dual
connect by level <= 100;
The table in montly intrval partitioned and contains 100 days of data - yielding in one initial partition and 4 new montly partition.
PARTITION_NAME HIGH_VALUE
------------------------------ --------------------------------------------------------------------------------
PART_01 TO_DATE(' 2019-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93334 TO_DATE(' 2019-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93335 TO_DATE(' 2019-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93336 TO_DATE(' 2019-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93337 TO_DATE(' 2019-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
Now we switch to daily partitioning
ALTER TABLE test SET INTERVAL (NUMTODSINTERVAL(1,'DAY'));
This makes nothing with existing data (so it is instant operation), also the new data for the current month will go in the current (month) partition.
The data loaded for the new month will be partitioned on daily basis.
Lets insert few new days
insert into test (dt)
select date'2019-01-01' + 100 +rownum dt from dual
connect by level <= 22;
PARTITION_NAME HIGH_VALUE
------------------------------ --------------------------------------------------------------------------------
PART_01 TO_DATE(' 2019-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93334 TO_DATE(' 2019-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93335 TO_DATE(' 2019-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93336 TO_DATE(' 2019-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93337 TO_DATE(' 2019-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93338 TO_DATE(' 2019-05-02 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93339 TO_DATE(' 2019-05-03 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93340 TO_DATE(' 2019-05-04 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
As expected starting with May the data are daily partitioned.
If you need also to re-partitioned your historical data, this will require reorganisation (data movement - will take some time for 120GB) using split partition.
alter table test
SPLIT PARTITION FOR(TO_DATE('2019-02-01','yyyy-mm-dd'))
AT (TO_DATE('2019-02-27','yyyy-mm-dd'));
alter table test
SPLIT PARTITION FOR(TO_DATE('2019-02-01','yyyy-mm-dd'))
AT (TO_DATE('2019-02-26','yyyy-mm-dd'));
This splits the last day in a new partition, you'll have to do it for each day in each monthly partition.
After this step also the history data is partitioned per day:
select * from test partition for ( DATE'2019-02-26');
DT
-------------------
26.02.2019 00:00:00

Can i change range interval partition from month to day in oracle

I have a table which is partitioned as below and has millions of rows of data. Table size is 120 GB.
PARTITION BY RANGE (Read_time) INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
Now I want to change to this partitioning strategy with existing data and future data. Table is inserted daily by job.
PARTITION BY RANGE (Read_time) INTERVAL(NUMTODSINTERVAL(1, 'DAY'))
I have 12 month partition (Oct'18 to Nov'19). I want partition to be converted to daywise.
For example: For Jul'19 partition, it should to be splitted to
01 Jul'19,
02 Jul'19
.......
31 Jul'19.
Data should also be moved to new partition
I tried split partition. New partition got created day wise , but rows didn't move to new partition.
To change for monthly interval to daily is a simple as
ALTER TABLE test SET INTERVAL (NUMTODSINTERVAL(1,'DAY'));
see the documentation for further details
Lets illustrate in on a small example
create table test
(dt date)
PARTITION BY RANGE (dt)
INTERVAL (NUMTOYMINTERVAL(1,'MONTH'))
(
PARTITION part_01 values LESS THAN (TO_DATE('01-01-2019','DD-MM-YYYY'))
);
insert into test (dt)
select date'2019-01-01' + rownum dt from dual
connect by level <= 100;
The table in montly intrval partitioned and contains 100 days of data - yielding in one initial partition and 4 new montly partition.
PARTITION_NAME HIGH_VALUE
------------------------------ --------------------------------------------------------------------------------
PART_01 TO_DATE(' 2019-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93334 TO_DATE(' 2019-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93335 TO_DATE(' 2019-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93336 TO_DATE(' 2019-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93337 TO_DATE(' 2019-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
Now we switch to daily partitioning
ALTER TABLE test SET INTERVAL (NUMTODSINTERVAL(1,'DAY'));
This makes nothing with existing data (so it is instant operation), also the new data for the current month will go in the current (month) partition.
The data loaded for the new month will be partitioned on daily basis.
Lets insert few new days
insert into test (dt)
select date'2019-01-01' + 100 +rownum dt from dual
connect by level <= 22;
PARTITION_NAME HIGH_VALUE
------------------------------ --------------------------------------------------------------------------------
PART_01 TO_DATE(' 2019-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93334 TO_DATE(' 2019-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93335 TO_DATE(' 2019-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93336 TO_DATE(' 2019-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93337 TO_DATE(' 2019-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93338 TO_DATE(' 2019-05-02 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93339 TO_DATE(' 2019-05-03 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P93340 TO_DATE(' 2019-05-04 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
As expected starting with May the data are daily partitioned.
If you need also to re-partitioned your historical data, this will require reorganisation (data movement - will take some time for 120GB) using split partition.
alter table test
SPLIT PARTITION FOR(TO_DATE('2019-02-01','yyyy-mm-dd'))
AT (TO_DATE('2019-02-27','yyyy-mm-dd'));
alter table test
SPLIT PARTITION FOR(TO_DATE('2019-02-01','yyyy-mm-dd'))
AT (TO_DATE('2019-02-26','yyyy-mm-dd'));
This splits the last day in a new partition, you'll have to do it for each day in each monthly partition.
After this step also the history data is partitioned per day:
select * from test partition for ( DATE'2019-02-26');
DT
-------------------
26.02.2019 00:00:00

Query joined partitioned tables

I have 2 partitioned tables . I want to left joined them it means that i want all record of table 'A' that is in specific date , and data in table 'B' if there is any matched record (also in specific date). both tables are partitioned so i use partitioned column (time) in where clause , but in this query when there is not any matched record in table 'B' , the condition 'B.time' become null and the records of table 'A' dose not appear in result.
if I do not use time condition for table 'B', the execution plan of it become partition range all and has bad performance .
how can i edit the query?
select * from A left outer join B SSRESP
on A.ID = B.A_ID where
A.time >= to_date('1396/09/26 00:00:00',
'yyyy/mm/dd hh24:mi:ss',
'NLS_CALENDAR=persian')
and A.time <= to_date('1396/10/27 11:00:00',
'yyyy/mm/dd hh24:mi:ss',
'NLS_CALENDAR=persian')
and B.time >=
to_date('1396/09/26 00:00:00',
'yyyy/mm/dd hh24:mi:ss',
'NLS_CALENDAR=persian')
and B.time <=
to_date('1396/10/27 11:00:00',
'yyyy/mm/dd hh24:mi:ss',
'NLS_CALENDAR=persian')
There are 2 possibilities.
1) Move the condition to the on-clause:
select *
from A
left outer join B
on A.ID = B.A_ID
and B.time >= to_date('1396/09/26 00:00:00',
'yyyy/mm/dd hh24:mi:ss',
'NLS_CALENDAR=persian')
and B.time <= to_date('1396/10/27 11:00:00',
'yyyy/mm/dd hh24:mi:ss',
'NLS_CALENDAR=persian')
where A.time >= to_date('1396/09/26 00:00:00',
'yyyy/mm/dd hh24:mi:ss',
'NLS_CALENDAR=persian')
and A.time <= to_date('1396/10/27 11:00:00',
'yyyy/mm/dd hh24:mi:ss',
'NLS_CALENDAR=persian')
2) Filter the table before the left join:
select *
from A
left outer join
(SELECT * FROM B
WHERE B.time >= to_date('1396/09/26 00:00:00',
'yyyy/mm/dd hh24:mi:ss',
'NLS_CALENDAR=persian')
and B.time <= to_date('1396/10/27 11:00:00',
'yyyy/mm/dd hh24:mi:ss',
'NLS_CALENDAR=persian')) AS B
on A.ID = B.A_ID
where A.time >= to_date('1396/09/26 00:00:00',
'yyyy/mm/dd hh24:mi:ss',
'NLS_CALENDAR=persian')
and A.time <= to_date('1396/10/27 11:00:00',
'yyyy/mm/dd hh24:mi:ss',
'NLS_CALENDAR=persian')

Change the range of existing partition

I have a table with two partitions:
create table MY
(
id NUMBER not null,
dat DATE
)
partition by range (dat)
(
partition PART_ARCHIVE values less than (TO_DATE(' 2015-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
tablespace ARCHIVE,
partition PART_ACTUAL values less than (MAXVALUE) tablespace ACTUAL
);
Can I change the PART_ARCHIVE partition date interval without recreating table?
I need to set that:
partition PART_ARCHIVE values less than (TO_DATE(' 2017-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
I don't know whether you can do it in a single command but this one should work:
ALTER TABLE MY SPLIT PARTITION PART_ACTUAL INTO
(PARTITION PART_2017 VALUES LESS THAN (DATE '2017-01-01'),
PARTITION PART_ACTUAL);
ALTER TABLE MY MERGE PARTITIONS PART_2017, PART_ARCHIVE INTO PART_ARCHIVE;

Want to round the data

My Query is :
SELECT TO_CHAR((to_date('01-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS')+ (level-1)),'DD-MM-YYYY'),
TO_CHAR(to_date('01-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS') + level,'DD-MM-YYYY') ,
to_number(regexp_substr('7000 T', '^\d+'))/(TO_DATE('04-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS') - TO_DATE('01-01-2018 00:00', 'DD-MM-YYYY HH24:MI:SS'))
|| regexp_substr('7000 T', '[A-Z]') AS IP_PLAN
FROM dual
CONNECT BY level <= to_date('04-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS')-to_date('01-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS');
I want IP_PLAN like: 2333 T
ROUND(('7000 T'), '[A-Z]') is trying to round a string value, i.e. the T that is extracted from that source string, which doesn't make sense.
You need to round the number you generated just before that:
select to_char(to_date('01-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS') + level - 1,
'DD-MM-YYYY'),
to_char(to_date('01-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS') + level,
'DD-MM-YYYY') ,
round(
to_number(regexp_substr('7000 T', '^[[:digit:]]+'))
/ (to_date('04-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS')
- to_date('01-01-2018 00:00', 'DD-MM-YYYY HH24:MI:SS'))
)
|| regexp_substr('7000 T', '[^[:digit:]]*$') as ip_plan_consumption
from dual
connect by level <= to_date('04-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS')
- to_date('01-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS');
TO_CHAR(TO TO_CHAR(TO IP_PLAN_CONSUMPTION
---------- ---------- ------------------------------------------
01-01-2018 02-01-2018 2333 T
02-01-2018 03-01-2018 2333 T
03-01-2018 04-01-2018 2333 T
so you're doing
round(<number extracted by regex> / <difference in days >)
which is
round(7000 / 3) => round(2333.333...) => 2333
and then appending the T after wards.
I've changed the regex patterns slightly so it picks up the space ans any characters at the end. That's making some assumptions about possible values in that string though - i.e. that it's always one number followed by one non-numeric section.
Incidentally, if you're using fixed dates then it's simpler to use date literals:
select to_char(date '2018-01-01' + level - 1, 'DD-MM-YYYY'),
to_char(date '2018-01-01' + level, 'DD-MM-YYYY') ,
round(
to_number(regexp_substr('7000 T', '^[[:digit:]]+'))
/ (date '2018-01-04' - date '2018-01-01')
)
|| regexp_substr('7000 T', '[^[:digit:]]*$') as ip_plan_consumption
from dual
connect by level <= date '2018-01-04' - date '2018-01-01';
though I imagine the 7000 T and the date values are all being passed in as string in your real code so they need to be converted. You could use a CTE to only convert them once though, instead of repeatedly as you loop round.
SELECT TO_CHAR((to_date('01-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS')+ (level-1)),'DD-MM-YYYY'),
TO_CHAR(to_date('01-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS') + level,'DD-MM-YYYY') ,
round(to_number(regexp_substr('7000 T', '^\d+'))/(TO_DATE('04-01-2018 00:00:00', 'DD-MM-YYYY HH24:MI:SS') - TO_DATE('01-01-2018 00:00', 'DD-MM-YYYY HH24:MI:SS')),0)
AS IP_PLAN_CONSUMPTION
FROM dual
CONNECT BY level <= to_date('04-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS')-to_date('01-01-2018 00:00:00','DD-MM-YYYY HH24:MI:SS');
you have to use T in some other column;

Resources