Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Partial Unique defferable / 3 сообщений из 3, страница 1 из 1
04.10.2017, 18:24
    #39531019
fsmoke
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Partial Unique defferable
Как, сделать подобную штуку

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

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
05.10.2017, 13:56
    #39531475
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Partial Unique defferable
проверьте, сейчас сочинил

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


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