Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Constraint: как такой сделать  [new]
Constraint_id1id2_id2id1
Guest
Коллеги, подскажите как сделать constraint.

Есть таблица с такими данными:
declare @t table(
id1 int null
,id2 int null
)

insert into @t(id1, id2)
select 1, 6
union all
select 6, 1
union all
select 4, 3

select * from @t


Нужно, чтобы была уникальность по id1 + id2 и ключи не пересекались с id2 + id1.

Т.е. из искомого примера
1, 6
и
6, 1 это дубли и одна запись в таблицу попасть не должна.

Как сделать такое ограничение?
1 июн 15, 15:09    [17715778]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
declare @t table(
    id1 int null
    , id2 int null

    , id_min as case when id1 < id2 then id1 else id2 end
    , id_max as case when id1 > id2 then id1 else id2 end

    , unique (
        id_min
        , id_max
    )
)

insert into @t(id1, id2)
select 1, 6
insert into @t(id1, id2)
select 6, 1
insert into @t(id1, id2)
select 4, 3

select * from @t


Сообщение было отредактировано: 1 июн 15, 15:12
1 июн 15, 15:11    [17715791]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4902
А если полей будет штук 5?
1 июн 15, 15:49    [17716036]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Constraint_id1id2_id2id1
Коллеги, подскажите как сделать constraint.

Есть таблица с такими данными:
declare @t table(
id1 int null
,id2 int null
)

insert into @t(id1, id2)
select 1, 6
union all
select 6, 1
union all
select 4, 3

select * from @t


Нужно, чтобы была уникальность по id1 + id2 и ключи не пересекались с id2 + id1.

Т.е. из искомого примера
1, 6
и
6, 1 это дубли и одна запись в таблицу попасть не должна.

Как сделать такое ограничение?


не ясно, уникальность по сумме: 4+3=7?
1 июн 15, 15:57    [17716090]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Winnipuh
Constraint_id1id2_id2id1
Коллеги, подскажите как сделать constraint.

Есть таблица с такими данными:
declare @t table(
id1 int null
,id2 int null
)

insert into @t(id1, id2)
select 1, 6
union all
select 6, 1
union all
select 4, 3

select * from @t



Нужно, чтобы была уникальность по id1 + id2 и ключи не пересекались с id2 + id1.

Т.е. из искомого примера
1, 6
и
6, 1 это дубли и одна запись в таблицу попасть не должна.

Как сделать такое ограничение?


не ясно, уникальность по сумме: 4+3=7?
Мне показалось, что множество значений полей из одной строки
не должно быть равным множеству значений этих же полей в какой-нибудь другой строке
и не должно содержать внутри себя равных элементов.
В принципе, можно написать скалярную функцию для CHECK.
На худой конец триггер.
1 июн 15, 16:01    [17716127]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8828
Constraint_id1id2_id2id1,
сделайте вычисляемое поле

concat(case when [f1]>[f2] then [f2] else [f1] end,',',case when [f1]>[f2] then [f1] else [f2] end)

и уникальный индекс по этому полю
1 июн 15, 16:05    [17716144]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
iap
Winnipuh
пропущено...


не ясно, уникальность по сумме: 4+3=7?
Мне показалось, что множество значений полей из одной строки
не должно быть равным множеству значений этих же полей в какой-нибудь другой строке
и не должно содержать внутри себя равных элементов.
В принципе, можно написать скалярную функцию для CHECK.
На худой конец триггер.


это да, согласен, но не суммами, интегральный признак не подходит в данном случае.
А не достаточно первого условия, сравнения элементов (упорядоченных) множеств?

Можно было бы добавить вычисляемое поле, которое бы содержало сумму элементов, и затем искать в этом подмножестве проверяемую запись.
1 июн 15, 16:06    [17716157]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Владислав Колосов
Constraint_id1id2_id2id1,
сделайте вычисляемое поле

concat(case when [f1]>[f2] then [f2] else [f1] end,',',case when [f1]>[f2] then [f1] else [f2] end)

и уникальный индекс по этому полю
А где же тут выравнивание строк по правому краю?
И чем это лучше уже предложенного 17715791?
1 июн 15, 16:08    [17716173]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
Constraint_id1id2_id2id1
Guest
Winnipuh,

нет, уникальность именно по паре значений.

to All,

спасибо
1 июн 15, 16:20    [17716251]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21249
CREATE FUNCTION fnCheck(@id1 INT, @id2 INT)
RETURNS int
AS 
BEGIN
   DECLARE @retval int
   SELECT @retval = COUNT(*) 
      FROM test 
      WHERE (test.id1 = @id1 AND test.id2 = @id2) 
         OR (test.id1 = @id2 AND test.id2 = @id1)
   RETURN @retval
END;

ALTER TABLE @t
ADD CONSTRAINT myCheck CHECK (fnCheck(id1, id2) < 2);
1 июн 15, 16:50    [17716451]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21249
Пардон... не всё поправил

CREATE FUNCTION fnCheck(@id1 INT, @id2 INT)
RETURNS int
AS 
BEGIN
   DECLARE @retval int
   SELECT @retval = COUNT(*) 
      FROM @t
      WHERE (@t.id1 = @id1 AND @t.id2 = @id2) 
         OR (@t.id1 = @id2 AND @t.id2 = @id1)
   RETURN @retval
END;

ALTER TABLE @t
ADD CONSTRAINT myCheck CHECK (fnCheck(id1, id2) < 2);
1 июн 15, 16:54    [17716478]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Akina
Пардон... не всё поправил

CREATE FUNCTION fnCheck(@id1 INT, @id2 INT)
RETURNS int
AS 
BEGIN
   DECLARE @retval int
   SELECT @retval = COUNT(*) 
      FROM @t
      WHERE (@t.id1 = @id1 AND @t.id2 = @id2) 
         OR (@t.id1 = @id2 AND @t.id2 = @id1)
   RETURN @retval
END;

ALTER TABLE @t
ADD CONSTRAINT myCheck CHECK (fnCheck(id1, id2) < 2);


а мне вот фукнции не нравятся, стремные они, особенно на больших таблицах.
1 июн 15, 16:55    [17716491]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21249
Winnipuh
стремные они, особенно на больших таблицах.

Это верно.
Но я не могу себе представить БОЛЬШУЮ таблицу, на которой может потребоваться такое ограничение.
1 июн 15, 17:13    [17716620]     Ответить | Цитировать Сообщить модератору
 Re: Constraint: как такой сделать  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Akina
Winnipuh
стремные они, особенно на больших таблицах.

Это верно.
Но я не могу себе представить БОЛЬШУЮ таблицу, на которой может потребоваться такое ограничение.


о, сколько на открытий чЮдных
1 июн 15, 17:22    [17716674]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить