Ниже Стандартный SQL, а не MySql диалекте, но MySql это имеет хороший уровень соответствия Стандарту, и я верю, что вы должны следовать моей точке.
Вы не опубликовать схему или образец данных, так что я должен был догадаться, что ваши таблицы может выглядеть следующим образом:
CREATE TABLE Mothers
(
mother_ID INTEGER NOT NULL UNIQUE
);
CREATE TABLE Children
(
child_ID INTEGER NOT NULL UNIQUE
);
CREATE TABLE MothersOfTwins
(
mother_ID INTEGER NOT NULL
UNIQUE REFERENCES Mothers (mother_ID),
twin_1_child_ID INTEGER
REFERENCES Children (child_ID),
twin_2_child_ID INTEGER
REFERENCES Children (child_ID),
CHECK (twin_1_child_ID <> twin_2_child_ID)
);
INSERT INTO Mothers (mother_ID) VALUES (101), (102), (103);
INSERT INTO Children (child_ID) VALUES (551), (552), (553), (554);
INSERT INTO MothersOfTwins (mother_ID, twin_1_child_ID, twin_2_child_ID)
VALUES
(101, 551, 552),
(102, 552, 551); -- duplicate
Это последний INSERT
успешно, даже если он должен терпеть неудачу т.е. перенося значения child_ID между рядами будет fool any UNIQUE
ограничение, которое вы хотите поместить в столбцы. Я думаю, это похоже на проблему, с которой вы сталкиваетесь.
Одним из решений этой проблемы состоит в создании базовой таблицы, которая требует нескольких строк для моделирования братьев, с использованием колонки «вхождение» с ограничением, чтобы гарантировать, что не может быть больше двух братьев и сестер (то есть близнецы):
DROP TABLE MothersOfTwins;
CREATE TABLE MothersOfTwinsBase
(
mother_ID INTEGER NOT NULL
REFERENCES Mothers (mother_ID),
twin_occurrence INTEGER NOT NULL
CHECK (twin_occurrence BETWEEN 1 AND 2),
twin_child_ID INTEGER NOT NULL UNIQUE
REFERENCES Children (child_ID),
UNIQUE (mother_ID, twin_occurrence)
);
INSERT INTO MothersOfTwinsBase (mother_ID, twin_occurrence, twin_child_ID)
VALUES
(101, 1, 551),
(101, 2, 552),
(102, 1, 553),
(103, 2, 554);
Затем вы можете воссоздать структуру данных вашей прежней базовой таблицы, используя VIEW
, например
CREATE VIEW MothersOfTwins
(
mother_ID,
twin_1_child_ID, twin_2_child_ID
)
AS
SELECT M1.mother_ID,
M1.twin_child_ID AS twin_1_child_ID,
M2.twin_child_ID AS twin_2_child_ID
FROM MothersOfTwinsBase AS M1
INNER JOIN MothersOfTwinsBase AS M2
ON M1.mother_ID = M2.mother_ID
AND M1.twin_occurrence = 1
AND M2.twin_occurrence = 2
UNION ALL
SELECT M1.mother_ID,
M1.twin_child_ID AS twin_1_child_ID,
NULL AS twin_2_child_ID
FROM MothersOfTwinsBase AS M1
WHERE NOT EXISTS (
SELECT *
FROM MothersOfTwinsBase AS M2
WHERE M1.mother_ID = M2.mother_ID
AND M2.twin_occurrence = 2
)
UNION ALL
SELECT M2.mother_ID,
NULL AS twin_1_child_ID,
M2.twin_child_ID AS twin_2_child_ID
FROM MothersOfTwinsBase AS M2
WHERE NOT EXISTS (
SELECT *
FROM MothersOfTwinsBase AS M1
WHERE M1.mother_ID = M2.mother_ID
AND M1.twin_occurrence = 1
);
Помещает уникальный индекс/ограничение на поле «что-то в этом роде»? –
Вы имеете в виду, что один из столбцов имеет то же значение, что и один из других столбцов в одной строке, или вы имеете в виду, что значения в столбце уникальны? –