PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Creazione di una sequenza di caratteri su postgreSQL

Sfida accettata;)

Non credo che ci sia un modo per farlo solo con il meccanismo di sequenza PostgreSQL ( 1 )Ma se hai davvero bisogno di qualcosa del genere (e sono abbastanza interessato al motivo per cui hai bisogno di qualcosa del genere), puoi eseguire una funzione che ti restituisca il valore successivo che desideri e inserirlo in un trigger.

Ad esempio, crea prima una tabella :

create table test (test_id varchar);

Usa una funzione come questa qui sotto

create or replace function next_id_test()
 returns trigger language plpgsql as $function$
begin
    with cte_conform_char_list as
    (
        select val, row_number() over (order by val), lead(val) over (order by val)
        from (values ('A'), ('B'), ('C'), ('D'), ('E'), ('F')) as t(val) -- you can continue this list as much as you want it ;)
        order by 1
    )
    , cte_built_char_list as
    (
        select 
            cte.val
            , cte.row_number
            , coalesce(cte.lead, cte_2.val) as next_char
        from cte_conform_char_list cte
            left outer join cte_conform_char_list cte_2
                on cte_2.row_number = cte.row_number - (select max(row_number) from cte_conform_char_list) +1
    )
    select 
        case 
            when row_number < (select max(row_number) from cte_built_char_list)
                then repeat(next_char, cast(rank() over (partition by row_number order by test_id) as int)) 
                else repeat(next_char, cast(rank() over (partition by row_number order by test_id) + 1 as int))
        end as next_test_id into new.test_id
    from test T
        inner join cte_built_char_list cte on substring(T.test_id from 1 for 1) = cte.val
    order by char_length(test_id), test_id;

    return new;
end;
$function$;

Collega la funzione a un trigger precedente

create trigger tg_test before insert on test for each row execute procedure next_id_test();

Inserisci un valore che non ha importanza (verrà comunque modificato)

insert into test values ('ttt');

Quindi puoi osservare di avere il carattere giusto.

select *
from test;

So che è un modo un po' pesante ma non ne vedo nessun altro. Probabilmente la funzione non è perfetta ma non ho molto tempo :)

Spero che ti possa aiutare;)