How can I split maxvalue partition in Oracle with new subpartition template.
Or
How can I split maxvalue partition in Oracle and add also add new subpartitions parallely
You can use SPLIT PARTITION as following:
Oracle setup:
SQL> CREATE TABLE PART_EXAMPLE (
2 ID NUMBER,
3 CREATED_DATE DATE
4 )
5 PARTITION BY RANGE (
6 CREATED_DATE
7 )
8 ( PARTITION T1_2019
9 VALUES LESS THAN ( MAXVALUE )
10 );
Table created.
Checking the partitions:
SQL> SELECT
2 TABLE_NAME,
3 PARTITION_NAME
4 FROM
5 USER_TAB_PARTITIONS
6 WHERE TABLE_NAME = 'PART_EXAMPLE';
TABLE_NAME PARTITION_
--------------- ----------
PART_EXAMPLE T1_2019
Splitting the partition into two partitions:
SQL> ALTER TABLE PART_EXAMPLE
2 SPLIT PARTITION T1_2019 AT (TO_DATE('31-DEC-2017 23:59:59', 'DD-MON-YYYY HH24:MI:SS'))
3 INTO (PARTITION T1_2017, PARTITION T1_2019)
4 ONLINE;
Table altered.
Now, Checking the partitions:
SQL> SELECT
2 TABLE_NAME,
3 PARTITION_NAME
4 FROM
5 USER_TAB_PARTITIONS
6 WHERE TABLE_NAME = 'PART_EXAMPLE';
TABLE_NAME PARTITION_
--------------- ----------
PART_EXAMPLE T1_2017
PART_EXAMPLE T1_2019
SQL>
I hope it is clear.
Cheers!!
You can set the subpartitions template for a table. But this only affects new partitions. It has no impact on existing partitions:
create table t (
c1 int, c2 int
) partition by range ( c1 )
subpartition by hash ( c2 )
subpartition template 2
(
partition p0 values less than ( 1 ),
partition pmax values less than ( maxvalue )
);
select partition_name, subpartition_name
from user_tab_subpartitions
where table_name = 'T';
PARTITION_NAME SUBPARTITION_NAME
P0 SYS_SUBP2922
P0 SYS_SUBP2923
PMAX SYS_SUBP2924
PMAX SYS_SUBP2925
alter table t
set subpartition template 1;
select partition_name, subpartition_name
from user_tab_subpartitions
where table_name = 'T';
PARTITION_NAME SUBPARTITION_NAME
P0 SYS_SUBP2922
P0 SYS_SUBP2923
PMAX SYS_SUBP2924
PMAX SYS_SUBP2925
You can also set the template while splitting. But again, this doesn't affect the existing partitions:
alter table t
split partition pmax at ( 2 )
into (
partition p1 set subpartition template 1,
partition pmax set subpartition template 1
);
select partition_name, subpartition_name
from user_tab_subpartitions
where table_name = 'T';
PARTITION_NAME SUBPARTITION_NAME
P0 SYS_SUBP2922
P0 SYS_SUBP2923
P1 SYS_SUBP2926
P1 SYS_SUBP2927
PMAX SYS_SUBP2924
PMAX SYS_SUBP2925
If you want to change the subpartitions while splitting a partition, define them in the subpartitions clause:
alter table t
split partition pmax at ( 3 )
into (
partition p2 subpartitions 1,
partition pmax subpartitions 4
);
select partition_name, subpartition_name
from user_tab_subpartitions
where table_name = 'T';
PARTITION_NAME SUBPARTITION_NAME
P0 SYS_SUBP2936
P0 SYS_SUBP2937
P1 SYS_SUBP2940
P1 SYS_SUBP2941
P2 SYS_SUBP2942
PMAX SYS_SUBP2943
PMAX SYS_SUBP2944
PMAX SYS_SUBP2945
PMAX SYS_SUBP2946
Related
Best way to get high value of partition from oracle database?
"Best" is subjective but you can retrieve the high values by quering the data dictionary:
SELECT partition_name,
high_value
FROM USER_TAB_PARTITIONS
WHERE table_name = 'YOUR_TABLE_NAME';
One way is to use XML
create table t (
x date
) partition by range (x) (
partition p0 values less than (date'2015-01-01'),
partition p1 values less than (date'2015-06-01'),
partition pmax values less than (maxvalue)
);
with xml as (
select dbms_xmlgen.getxmltype('select table_name, partition_name, high_value from user_tab_partitions where table_name = ''T''') as x
from dual
)
select extractValue(rws.object_value, '/ROW/TABLE_NAME') table_name,
extractValue(rws.object_value, '/ROW/PARTITION_NAME') partition,
extractValue(rws.object_value, '/ROW/HIGH_VALUE') high_value
from xml x,
table(xmlsequence(extract(x.x, '/ROWSET/ROW'))) rws;
TABLE_NAME PARTITION HIGH_VALUE
---------- ---------- ------------------------------------------------------------------------------------------
T P0 TO_DATE(' 2015-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
T P1 TO_DATE(' 2015-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
T PMAX MAXVALUE
create table TEST_TABLE_2
(
report_month DATE,
name varchar(128)
)
partition by list (REPORT_MONTH)
(
partition TEST_PART_2022_05_31 values (TO_DATE(' 2022-05-31 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
tablespace TEST_TABLESPACE,
partition MONTH_UNKNOWN values (default)
tablespace TEST_TABLESPACE
);
create table TEST_TABLE_1
(
report_month DATE,
name varchar(128)
)
partition by list (REPORT_MONTH)
(
partition TEST_PART_2022_05_31 values (TO_DATE(' 2022-05-31 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
tablespace TEST_TABLESPACE,
partition MONTH_UNKNOWN values (default)
tablespace TEST_TABLESPACE
);
Advise me please, How I can to exchange partition TEST_PART_2022_05_31 from TEST_TABLE_2 with partition TEST_PART_2022_05_31 in TEST_TABLE_1?
WHen I exec this script
ALTER TABLE ADS.test_table_1
EXCHANGE PARTITION TEST_PART_2022_05_31
WITH TABLE ADS.test_table_2
I get Error: ORA-14095: ALTER TABLE EXCHANGE requires a non-partitioned, non-clustered table
Are you looking for something like this?
create table t (
c1, c2, c3
) partition by range ( c2 )
interval ( interval '1' month ) (
partition p0 values less than ( date'2022-02-01' )
)
as
select level, date'2022-01-01' + level, 'remove'
from dual
connect by level <= 100;
create table temp
for exchange with table t;
select count(*) from temp;
0
alter table t
exchange partition p0
with table temp;
select count(*) from temp;
100
Well, I am going to convert the epoch into a normal datetime in oracle sqldeveloper, I wrote the below code, but it says "missing expression"
My code:
SELECT to_date(CreationDate, 'yyyymmdd','nls_calendar=persian')+ EpochDate/24/60/60
from table1
My table1:
ID
EpochDate
100
16811048
101
16810904
102
12924715
103
15667117
I don not know what is wrong!
If the CreationDate is a Date and EpochDate is a Varchar you can try this:
SELECT to_date(to_char(CreationDate, 'yyyymmdd','nls_calendar=persian'),'yyyymmdd') +
EpochDate/24/60/60 as newDate
from table1
or:
select to_date(to_char(CreationDate, 'yyyymmdd','nls_calendar=persian'),'yyyymmdd') +
numtodsinterval(EpochDate,'SECOND') as newDate
from dual
Let's show you how in an example
Demo data
SQL> create table c1 ( id number generated always as identity, date_test date) ;
Table created.
SQL> insert into c1 ( date_test ) values ( sysdate ) ;
1 row created.
SQL> insert into c1 ( date_test ) values ( sysdate-365 ) ;
1 row created.
SQL> insert into c1 ( date_test ) values ( sysdate-4000 ) ;
1 row created.
SQL> insert into c1 ( date_test ) values ( sysdate-7200 ) ;
1 row created.
SQL> commit ;
Commit complete.
Now, let's add a column called epoch, and a small function to make easier to update the column.
SQL> alter table c1 add epoch number ;
Table altered.
SQL> create or replace function date_to_unix_ts( PDate in date ) return number is
l_unix_ts number;
begin
l_unix_ts := ( PDate - date '1970-01-01' ) * 60 * 60 * 24;
return l_unix_ts;
end;
/
Function created
We update the column epoch with the real epoch date based on the timestamp field
SQL> update c1 set epoch=date_to_unix_ts (date_test) ;
4 rows updated.
SQL> select * from c1 ;
ID DATE_TEST EPOCH
---------- ---------------------------------------- -----------------
1 2021-09-15 12:25:25 1631708725
2 2020-09-15 12:25:25 1600172725
3 2010-10-03 12:25:25 1286108725
4 2001-12-29 12:25:26 1009628726
SQL> select to_char(to_date('1970-01-01','YYYY-MM-DD') + numtodsinterval(EPOCH,'SECOND'),'YYYY-MM-DD HH24:MI:SS') from c1 ;
TO_CHAR(TO_DATE('19
-------------------
2021-09-15 12:25:25
2020-09-15 12:25:25
2010-10-03 12:25:25
2001-12-29 12:25:26
For example, create a table in hive.
CREATE TABLE t_data_daily(
imp_date BIGINT,
sp STRING,
datax STRING
)
PARTITION BY LIST( imp_date )
SUBPARTITION BY LIST( sp )(
SUBPARTITION sp_1 VALUES IN ( 'sp_1' ),
SUBPARTITION sp_2 VALUES IN ( 'sp_2' ),
SUBPARTITION sp_3 VALUES IN ( 'sp_3' )
)
(
PARTITION p_20191030 VALUES IN ( 20191030 ),
PARTITION p_20191101 VALUES IN ( 20191101 ),
PARTITION p_20191122 VALUES IN ( 20191122 )
)
select data with specific partition:
select * from t_data_daily partition (p_20191030) x limit 100
How to select data from specific partition and sub-partition?
Except the following:
select * from t_data_daily partition (p_20191030) x where sp = 'sp_1' limit 100
I have a table with following structure,
CREATE TABLE test_range_partition (
table_name VARCHAR2(30),
order_date DATE,
num_rows NUMBER
) PARTITION BY RANGE(num_rows) (
PARTITION num_rows1 VALUES LESS THAN (100) TABLESPACE part1,
PARTITION num_rows2 VALUES LESS THAN (1000) TABLESPACE part2,
PARTITION num_rows3 VALUES LESS THAN (10000) TABLESPACE part3,
PARTITION num_rows4 VALUES LESS THAN (MAXVALUE) TABLESPACE part4
);
If I want to select data
select * from test_range_partition where num_rows =100
which partition is selected?
num_rows1 contain 1 to 99
num_rows2 contain 100 to 999
num_rows1 contain 1000 to 9999 and so on
So your answer is num_rows2