Je pense que cela peut être plus facile à expliquer avec un exemple, alors disons que nous avons une base de données comme celle-ci:
Interventions , qui stocke l'ID et quoi que ce soit
besoins. Médecins . Outils . DoctorsOnInterventions ToolsOnInterventions Ok, maintenant nous pouvons faire:
+-----------------+------------+-----------------+ | InterventionId | Doctors | Tools | +-----------------+------------+-----------------+ | 1 | Tom, John | Scalpel, Hammer | | 2 | Tom, Homer | Hammer, Bulb | +-----------------+------------+-----------------+
Et obtenir:
+-----------------+------------+ | InterventionId | Doctors | +-----------------+------------+ | 1 | Tom, John | | 2 | Tom, Homer | +-----------------+------------+
Mais nous avons besoin pour ajouter une autre colonne, tout comme Doctors, mais avec les outils utilisés dans cette intervention, quelque chose comme ceci:
SELECT InterventionId, STRING_AGG(Doctors.Name, ', ') FROM Interventions INNER JOIN Doctors ON Doctors.Id = DoctorsOnInterventions.DoctorId GROUP BY Intervention.Id, Doctors.Id;
Il serait facile de faire encapsuler le code précédent sur une sous-requête puis en créant un autre groupe par , mais je me demandais s'il y avait un moyen plus correct de le faire car mes tables de base de données ont quelques dizaines de colonnes.
3 Réponses :
Vous pouvez utiliser string_agg () . Je recommanderais des sous-requêtes; apply peut être utilisé:
SELECT i.*, d.doctors, t.tools
FROM Interventions i OUTER APPLY
(SELECT STRING_AGG(d.name, ',') as doctors
FROM DoctorsOnInterventions doi JOIN
Doctors d
ON d.Id = doi.DoctorId
WHERE doi.interventionId = i.id
) d OUTER APPLY
(SELECT STRING_AGG(t.name, ',') as tools
FROM ToolsOnInterventions toi JOIN
Tools t
ON t.id = toi.ToolId
WHERE toi.interventionId = i.id
) t ;
Dans les anciennes versions de SQL Server, vous pouvez utiliser la méthode FOR XML PATH de concaténation de chaînes.
Je pense que vous aurez besoin d'une autre table pour les relier alors.
Interventions de table
SELECT InterventionId, STRING(Doctors.Name, ', ') FROM Interventions I WITH (NOLOCK) INNER JOIN Doctors D WITH (NOLOCK) ON D.Id = I.DoctorId INNER JOIN Interventions_tool IT WITH (NOLOCK) ON I.Id = IT.ToolId GROUP BY I.Id, D.Id; +-----------------+------------+-----------------+ | InterventionId | Doctors | Tools | +-----------------+------------+-----------------+ | 1 | Tom, John | Scalpel, Hammer | | 2 | Tom, Homer | Hammer, Bulb | +-----------------+------------+-----------------+
Outils de table
+-----------------+------------+ | InterventionId | ToolId | +-----------------+------------+ | 1 | 1 | | 2 | 2 | +-----------------+------------+
Table Interventions_tool ( nouveau )
+-----------------+----------------+ | InterventionId | Doctors | +-----------------+----------------+ | 1 | Scalpel, Hammer| | 2 | Hammer, Bulb | +-----------------+----------------+
La requête sera
+-----------------+------------+ | InterventionId | Doctors | +-----------------+------------+ | 1 | Tom, John | | 2 | Tom, Homer | +-----------------+------------+
Oui, je l'ai écrit, je l'ai appelé ToolsOnInterventios
@ CarlosLópezMarí Je n'ai pas compris? Avez-vous utilisé la suggestion?
SELECT InterventionId, STRING(Doctors.Name, ', '),STRING(Tools.name,',') FROM Interventions INNER JOIN Doctors ON Doctors.Id = DoctorsOnInterventions.DoctorId INNER JOIN Tools on tools.id = ToolsOnInterventions.toolsid GROUP BY Intervention.Id, Doctors.Id, tools.id;
Si vous groupez par ces 3, vous obtiendrez pour chaque médecin toutes les combinaisons d'outils utilisées, ce n'est pas ce dont j'ai besoin.
Qu'est-ce que la fonction
STRING ()?Ce n'est pas un t-sql valide. Je ne connais aucune version de sql qui a STRING comme fonction. Que diriez-vous des définitions de table, des exemples de données et de quelque chose de valide pour une requête?
Quel type de relation existe-t-il entre les tableaux Interventions et Outils? Vous ne pouvez associer des tables que si comment avoir au moins une colonne entre elles
@GordonLinoff l'a corrigé