powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Partial Unique defferable
3 сообщений из 3, страница 1 из 1
Partial Unique defferable
    #39531019
fsmoke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как, сделать подобную штуку

Допустим есть таблица

CREATE TABLE public.tree123
(
id uuid NOT NULL,
parent uuid,
"order" integer NOT NULL,
CONSTRAINT tree123_pkey PRIMARY KEY (id),
CONSTRAINT tree123_check_parent FOREIGN KEY (parent)
REFERENCES public.tree123 (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)

Вопрос:
Как сделать уникальный "order" в пределах одного родителя(parent ) ?

Если я пишу так, всё работает, но только если parent не null

Код: plsql
1.
CONSTRAINT tree123_parent_order_key UNIQUE (parent, "order") DEFERRABLE



Если parent == null, то данный констрейнт не работает - погуглил нашел что можно сделать partial index

Код: plsql
1.
2.
3.
4.
5.
CREATE UNIQUE INDEX tree123_parent_null_order_idx
    ON public.tree123 USING btree
    (order)
    TABLESPACE pg_default   WHERE parent IS NULL
;



Но его нельзя сделать DEFERRABLE.

Соответсвенно когда мне нужно сделать так
Код: plsql
1.
2.
3.
4.
5.
6.
UPDATE tree123 SET "order" = CASE "order" 
                      WHEN 1 THEN 2 
                      WHEN 2 THEN 1
                      ELSE "order"
                      END
 WHERE "order" IN(1, 2) and parent is not null;



это работает, а так нет :

Код: plsql
1.
2.
3.
4.
5.
6.
UPDATE tree123 SET "order" = CASE "order" 
                      WHEN 1 THEN 2 
                      WHEN 2 THEN 1
                      ELSE "order"
                      END
 WHERE "order" IN(1, 2) and parent is null;



PS

PSQL 9.6
...
Рейтинг: 0 / 0
Partial Unique defferable
    #39531475
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
проверьте, сейчас сочинил

exclude ((coalesce(parent, uuid_nil())) with =, "order" with =) deferrable

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
rollback;

begin;

create table tree(
    id uuid not null,
    parent uuid,
    "order" integer not null,
    primary key(id),
    foreign key(parent) references tree,
    exclude ((coalesce(parent, uuid_nil())) with =, "order" with =) deferrable
);

with parent as(
    select uuid_generate_v4() as id
    , row_number() over() as rn
    from generate_series(1, 5)
), child as (
    select uuid_generate_v4() as id
    , parent.id as parent_id
    , row_number() over(partition by parent.id) as rn
    from parent, generate_series(1, 5)
) insert into tree(id, parent, "order") 
    select id, null, rn from parent
    union all
    select id, parent_id, rn from child;

update tree set "order" = 3 - "order" where "order" in(1, 2);

-- commit;

...
Рейтинг: 0 / 0
Partial Unique defferable
    #39533291
fsmoke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да работает всё супер, СПАСИБО
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Partial Unique defferable
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]