Votre problème est lié au concept de cardinalité des relations. Toutes les relations ont une certaine cardinalité, qui exprime le nombre potentiel d'instances de chaque côté de la relation qui en sont membres, ou peut participer à une instance unique de la relation. Par exemple, pour les personnes, (à part de rares exceptions), la relation Parent-Enfant a une cardinalité de 2 to zero or many
, ce qui signifie qu'il faut deux parents du côté parent, et qu'il peut y avoir zéro ou plusieurs enfants (En général, tout ce qui a un 1 (un), (ou un zéro ou un) d'un côté peut être facilement représenté avec seulement deux tables, une pour chaque entité (en général, 2 to 1 or many
)
, (parfois seule une table est nécessaire voir note **) et une colonne de clé étrangère dans la table représentant le côté "many", qui pointe vers l'autre table contenant l'entité du côté "un". Dans votre cas, vous avez une relation many to many
. (Une tâche peut avoir plusieurs prédécesseurs, et chaque prédécesseur peut certainement être le prédécesseur de plusieurs tâches) Dans ce cas, une troisième table est nécessaire, où chaque ligne représente effectivement une association entre deux tâches, représentant celle qui est le prédécesseur de la tâche. autre. Généralement, cette table est conçue pour contenir uniquement toutes les colonnes des clés primaires des deux tables parentes et sa propre clé primaire est un composite de toutes les colonnes dans les deux clés primaires parentes. Dans votre cas, il a simplement deux colonnes, le taskId, et le PredecessorTaskId, et cette paire d'identifiants doit être unique dans la table afin qu'ils forment ensemble le PK composite. Lors de l'interrogation, pour éviter le double comptage des colonnes de données dans les tables parentes lorsqu'il existe plusieurs jointures, basez simplement la requête sur la table parente ... par exemple, pour trouver la durée du parent le plus long, En supposant votre table d'association est nommé TaskPredecessor
Select TaskId, Max(P.Duration)
From Task T Join Task P
On P.TaskId In (Select PredecessorId
From TaskPredecessor
Where TaskId = T.TaskId)
** REMARQUE. Dans les cas où les deux entités de la relation appartiennent au même type d'entité, elles peuvent toutes deux être dans la même table. L'exemple canonique (luv ce mot) est une table d'employés avec la relation plusieurs à un de travailleur à superviseur ...Puisque le superviseur est également un employé, les employés et les superviseurs peuvent être dans la même table [Employee], et la realtionship peut être modélisée avec une clé étrangère (appelée par exemple SupervisorId) qui pointe vers une autre ligne dans la même table et contient l'ID du dossier de l'employé pour le superviseur de cet employé.
Peut-être devrais-je être plus précis. J'ai regardé dans le modèle de liste d'adjacence, mais je n'ai pas trouvé de bonnes manières de faire des choses comme l'enroulement de la durée de toutes mes tâches. Ce serait facile s'ils n'avaient pas plusieurs parents, mais comment puis-je tenir compte du fait que je ne veux pas la somme des deux parents, mais la plus longue durée de tous? – Ocelot20
@BPotocki: s'il vous plaît poster quelques exemples de données et le jeu de résultats que vous souhaitez obtenir. – Quassnoi