Voici standard SQL, plutôt que le dialecte mySQL, mais mySQL est a une bon niveau de conformité à la norme et j'espère que vous serez en mesure de suivre mon point de vue.
Vous ne pouvez pas poster votre schéma ou des données d'échantillon, donc je devais deviner ce que vos tables pourraient ressembler à:
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
Cette dernière INSERT
réussit même si elle devrait ne pas transposer à-dire les valeurs child_id entre les lignes seront tromper toute contrainte UNIQUE
que vous voulez mettre sur les colonnes. Je suppose que c'est semblable au problème auquel vous faites face.
Une solution à ce problème est de créer une table de base qui nécessite plusieurs lignes pour modéliser les frères et sœurs, en utilisant une colonne « occurrence » avec une contrainte pour assurer qu'il ne peut y avoir plus de deux frères et sœurs (c.-à-jumeaux):
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);
Vous pouvez ensuite recréer la structure de données de votre ancienne table de base à l'aide d'un VIEW
par exemple.
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
);
met un index unique/contrainte sur le champ « quelque chose comme ça »? –
Voulez-vous dire qu'une des colonnes a la même valeur que l'une des autres colonnes de la même ligne, ou voulez-vous dire que les valeurs de la colonne sont uniques? –