2009-05-10 8 views
3

Si j'ai une table de jointure avec deux colonnes, TeamA et TeamB, comment puis-je m'assurer que chaque paire est unique?Couples de colonnes uniques comme A, B ou B, A

Évidemment, je peux mettre un index composite unique sur ces colonnes mais cela ne fera que garantir l'unicité dans l'ordre A, B mais pas B, A correct? Comme vous pouvez le voir, Red vs Blue a déjà été spécifié comme premier enregistrement, puis il est spécifié à nouveau comme le dernier. Cela devrait être illégal car ils seront déjà en face l'un de l'autre.

Editer: Egalement, existe-t-il un moyen de gérer le cas SELECT? Ou la mise à jour? EFFACER? Etc ..

En outre, l'idée d'une équipe à domicile ou à l'étranger a été soulevée, ce qui peut être important ici. Ce concept initial m'est apparu en pensant à la façon de construire un système de bracketing du côté de la DB.

Répondre

2

Si votre SGBDR (vous n'avez pas spécifié) prend en charge les déclencheurs, créez un déclencheur sur cette table pour appliquer votre contrainte.

Créer un déclencheur qui se déclenche sur INSERT, qui vérifie si une paire existe déjà avec l'ordre inversé. Si elle fait ROLLBACK, sinon autoriser l'insertion.

+0

Pourriez-vous être plus précis? Je sais quels déclencheurs sont mais je ne les ai jamais utilisés. –

3

Définir une contrainte telle que, par exemple, la valeur dans la colonne A doit être (alphabétiquement ou numériquement) plus petite que la valeur de la colonne B: ainsi vous seriez autorisé à insérer {bleu, rouge} mais pas {rouge, bleu} parce que le bleu est moins que le rouge.

+0

Capture également le cas où vous ne pouvez pas avoir {rouge, rouge} ou {bleu, bleu}. – Apocalisp

+0

mais comment autorisez-vous {jaune, bleu}? C'est-à-dire que si TeamA est en jaune? –

+2

Cela signifierait essentiellement que l'application gère ce scénario. Y a-t-il un meilleur moyen? –

1

Voici un exemple de code à utiliser avec la méthode de déclenchement décrite par Mitch.

Je ne l'ai pas testé ce code, et il est tard dans la nuit ici :-)

CREATE TRIGGER trig_addTeam 
ON Teams 
FOR INSERT, UPDATE 
AS 

DECLARE @TeamA VARCHAR(100) 
DECLARE @TeamB VARCHAR(100) 
DECLARE @Count INT 

SELECT @TeamA = (SELECT TeamA FROM Inserted) 
SELECT @TeamB = (SELECT TeamB FROM Inserted) 

SELECT @Count = (SELECT COUNT(*) FROM TEAMS WHERE (TeamA = @TeamA AND TeamB = @TeamB) 
       OR (TeamA = @TeamB AND TeamB = @TeamA)) 

IF @Count > 0 THEN 

BEGIN 
    ROLLBACK TRANSACTION 
END 

Ce que cela fait est à la recherche pour voir si l'une séquence de A | B ou B | A existe dans le courant table. Si tel est le cas, le nombre renvoyé est supérieur à zéro et la transaction est annulée et non validée dans la base de données.

0

Si la même paire (inversée) existe, prenez celle où TeamA> TeamB.

SELECT DISTINCT TeamA, TeamB 
FROM table t1 
WHERE t1.TeamA > t1.TeamB 
    OR NOT EXISTS (
     SELECT * FROM table t2 
      WHERE t2.TeamA = t1.TeamB AND t2.TeamB = t1.TeamA 
    ) 
Questions connexes