Oracle Custom Sequence of a partitioned group (Insert trigger)
Not Possible

Your suggested Implementation of your Business Requirement is not possible.

You cannot select from table T1 from within a trigger on T1.  There are hacks around such limitation.  But, that is what they are: hacks.  One of them has a side effect of preventing you from performing a rollback.

In all cases: you'll still want to define a sequence for group_id.

create sequence group_id_seq;


Work Around - Correct your schema design

If you want to ensure that each Unique group_name contains a Unique group_id, then you need to create a table that enforces such data logic.

create table unique_groups (
   group_id    int generate by default on null as identity
  ,group_name  varchar2(50) not null
  ,constraint unique_group_pk primary key (group_id)
  ,constraint unique_group_uq1 unique (group_name)
);

alter table t1
  add constraint t1_fk1 foreign key (group_id) references unique_group( group_id );
alter table t1
  add constraint t1_fk2 foreign key (group_name) references unique_group( group_name );


Then, and only then, you can use a trigger.  (I'd still not advise it.)

create or replace
trigger t1_tr
before insert
on t1
for each row
begin
  select a.group_id into :new.group_id
  from unique_groups a
  where a.group_name = :new.group_name;
exception
  when no_data_found then
    insert into unique_groups (group_name)
    values (:new.group_name)
    returning group_id into :new.group_id;
end;
/


Work Around - TAPI

One work is the use of Table APIs (TAPI).

This is a Package that performs all necessary tasks to perform an insert,update, or delete.  Instead of your application performing the DML, the application calls the TAPI to perform the DML.

If necessary, you can wrap the Package with a VIEW and an INSTEAD OF trigger.

Package Spec:

create or replace package t1_tapi_pkg as
    -- I like to customize known exceptions for the application.
    data_corruption_detected   exception;
    PRAGMA EXCEPTION_INIT (data_corruption_detected, -20000);

    table_in_use_try_again     exception;
    PRAGMA EXCEPTION_INIT (lock_timeout, -20001);

    lock_timeout               exception;
    PRAGMA EXCEPTION_INIT (lock_timeout, -54);  -- These are caught and re-raised as -20001


    function ins (
        group_name in t1.group_name%type
    ) return t1.group_id%type;

    -- update logic has not been defined.

    -- regular SELECT and DELETE statements can be used.

end;
/


Package Body:

create or replace
package body t1_tapi_pkg
as

    function ins (
        group_name in t1.group_name%type
    ) return t1.group_id%type as
        group_id   t1.group_id;
    begin
        -- You should change to "WAIT 3"
        lock table t1 in exclusive mode nowait;

        begin
            -- find existing
            select distinct a.group_id
                into ins.group_id
            from t1 a
            where a.group_name = ins.group_name;

            -- re-use that value
            insert into t1 a (group_name, group_id)
            values ( ins.group_name, ins.group_id );

        exception
            when no_data_found then
                -- create a new unique value
                insert into t1 a (group_name, group_id)
                values ( ins.group_name, group_id_seq.nextval )
                returning a.group_id
                    into ins.group_id;
            when too_many_rows
                -- the GROUP_NAME does not have a unique GROUP_ID
                then raise data_corruption_detected;
        end;

        return ins.group_id;
    exception
        -- not necessary.  I like to customize my exceptions.
        when lock_timeout then
            raise table_in_use_try_again;
    end;
end;
/