I'm not aware of a way to do this. But when you add hash (sub)partitions, only moves rows from one of the existing partitions:
create table t (
record_ins_date date, business_id int,
source_system int, destination_system int
) partition by range ( record_ins_date )
subpartition by hash (
business_id, source_system, destination_system
) subpartitions 2 (
partition p_first_part values less than (
to_date ( '05-SEP-2017','DD-MON-YYYY' )
)
) ;
insert into t
select sysdate, rownum, rownum, rownum from dual
connect by level <= 1024;
commit;
select uo.object_name, uo.subobject_name, count(*)
from t, user_objects uo
where dbms_rowid.rowid_object(t.rowid) = uo.data_object_id
group by uo.object_name, uo.subobject_name
order by 1;
OBJECT_NAME SUBOBJECT_NAME COUNT(*)
T SYS_SUBP18241 504
T SYS_SUBP18242 520
alter table t modify partition p_first_part add subpartition;
select uo.subobject_name, count(*)
from t, user_objects uo
where dbms_rowid.rowid_object(t.rowid) = uo.data_object_id
group by uo.subobject_name
order by 1;
SUBOBJECT_NAME COUNT(*)
SYS_SUBP18241 237
SYS_SUBP18242 520
SYS_SUBP18243 267
alter table t modify partition p_first_part add subpartition;
select uo.subobject_name, count(*)
from t, user_objects uo
where dbms_rowid.rowid_object(t.rowid) = uo.data_object_id
group by uo.subobject_name
order by 1;
SUBOBJECT_NAME COUNT(*)
SYS_SUBP18241 237
SYS_SUBP18242 272
SYS_SUBP18243 267
SYS_SUBP18244 248
This makes the process relatively efficient. You're only ever moving ~half the rows out of one partition.
Read more about this from Jonathan Lewis at:
https://jonathanlewis.wordpress.com/2009/09/21/hash-partitions-2/#more-2242