Split maxvalue partition in Oracle with new subpartition template - sql

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 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

How I can to exchange partition in ORACLE. ORA-14095: ALTER TABLE EXCHANGE requires a non-partitioned, non-clustered table

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

convert epoch time into normal datetime format in Oracle SQL

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

Hive: how to select from specfic sub-partiton

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

Range partation

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