Range partation - sql

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

Related

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

Postgres partition by range from x and above condition

I am wondering how to partition a table like,
from 0 to 100
from 100 to 200
200 and above
CREATE TABLE grade_main
(
id serial not null,
g int not null
) partition by range (g);
CREATE TABLE grade_00_100 PARTITION OF grade_main FOR VALUES FROM (0) TO (100);
CREATE TABLE grade_100_200 PARTITION OF grade_main FOR VALUES FROM (100) TO (200);
-- The following returns syntax error
CREATE TABLE grade_150_all PARTITION OF grade_main FOR VALUES FROM (150);
To soecify a range that has no upper limit, use
FOR VALUES FROM (150) TO (MAXVALUE)

Split maxvalue partition in Oracle with new subpartition template

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

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

Delete old entries from table in MSSQL

a table in my MSSQL db is getting over 500MB. I would like to delete the x last entries so the table size is only 100MB. This should be a task which runs once a week. How could I do this?
Example:
Table before deleting the old entries:
Table after deleting the old entries:
You can use DATALENGTH to get the size of the data in a particular column. With a window function, you can sum up a running total of DATALENGTH values. Then you can delete all records in a table that push you past a desired max table size. Here's an example:
-- Sample table with a VARBINARY(MAX) column
CREATE TABLE tmp (id INT IDENTITY(1,1) PRIMARY KEY, col VARBINARY(MAX))
-- Insert sample data - 20 bytes per row.
;WITH cte AS
(
SELECT 1 AS rn, HASHBYTES('sha1', 'somerandomtext') t
UNION all
SELECT rn + 1, HASHBYTES('sha1', 'somerandomtext')
FROM cte
WHERE rn< 5000
)
INSERT INTO tmp (col)
SELECT t FROM cte
OPTION (maxrecursion 0)
-- #total_bytes is the desired size of the table after the delete statement
DECLARE #total_bytes int = 200
-- Use the SUM window function to get a running total of the DATALENGTH
-- of the VARBINARY field, and delete when the running total exceeds
-- the desired table size.
-- You can order the window function however you want to delete rows
-- in the correct sequence.
DELETE t
FROM tmp t
INNER JOIN
(
SELECT id, SUM(DATALENGTH(col)) OVER (ORDER BY id) total_size
FROM tmp
)sq ON t.id = sq.id AND sq.total_size > #total_bytes
Now check what's left in tmp: 10 rows, and the total size of the "col" column matches the 200 byte size specified in the #total_bytes variable.
UPDATE: Here's an example using your sample data:
CREATE TABLE tmp (id INT PRIMARY KEY, contact VARCHAR(100), country VARCHAR(25))
GO
INSERT INTO tmp VALUES
(1, 'Maria Anders', 'Germany'),
(2, 'Francisco Chang', 'Mexico'),
(3, 'Roland Mendel', 'Austria'),
(4, 'Helen Bennett', 'UK'),
(5, 'Yoshi Tannamuri', 'Canada'),
(6, 'Giovanni Rovelli', 'Italy')
GO
-- #total_bytes is the desired size of the table after the delete statement
DECLARE #total_bytes INT = 40
-- Use the SUM window function to get a running total of the DATALENGTH
-- of the VARBINARY field, and delete when the running total exceeds
-- the desired table size.
-- You can order the window function however you want to delete rows
-- in the correct sequence.
DELETE t
FROM tmp t
INNER JOIN
(
SELECT id, SUM(DATALENGTH(contact)) OVER (ORDER BY id)
+ SUM(DATALENGTH(country)) OVER (ORDER BY id) total_size
FROM tmp
)sq ON t.id = sq.id AND sq.total_size > #total_bytes
SELECT * FROM tmp -- 2 rows left!
DELETE FROM TABLE_NAME WHERE date_column < '2018-01-01';
This will delete all data that entered before January 2018
if you want to delete last 7days data
delete from table_name WHERE date_column >= DATEADD(day,-7, GETDATE())