Bonjour,
Contexte : Dans mon programme en C# j'effectue une requête SQL dans mon programme afin de récupérer les données dont j'ai besoin dans ma BDD AzureSQL et je remplis grâce à la requête un datagridview.
Je récupère des informations d'un plan dans une table et grâce à son ID je récupère les autres informations auxquelles il est associé dans d'autres tables comme par exemple des tensions et types de caténaires
Un plan peut donc être associé à plusieurs tensions et domaines dans les tables respectivement plans_into_voltage et plans_into_type.
Une fois les données associées récupérées, j'effectue un INNER JOIN entre les données pour avoir toutes les tensions d'un plan etc.
Voilà ma requête (vous m'exuserez, je n'ai pas utilisé de surnoms etc..) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| SELECT [allocation_schematic.information].primary_infos.plan_number 'Numéro de plan', [allocation_schematic.information].primary_infos.plan_name as 'Nom du plan',
CONVERT(varchar(20), [allocation_schematic.information].folders.number) as 'Dossier', [allocation_schematic.information].folders.name as 'Nom du dossier',
[allocation_schematic.types].voltage.name as 'Tension(s)', [allocation_schematic.types].catenary_type.name as 'Type(s) de caténaires',
[allocation_schematic.information].plans_versions.version as 'Indices', [allocation_schematic.information].plans_versions.creation_date as 'Date de création',
CONVERT(varchar(20),[allocation_schematic.information].plans_status.status) as 'Statut',
[allocation_schematic.fields].application_fields.number as 'Domaine(s) d''applications', [allocation_schematic.fields].application_fields.name as 'Nom du domaine'
FROM (((((((((( [allocation_schematic.information].primary_infos
INNER JOIN [allocation_schematic.types].plans_into_voltage on [allocation_schematic.types].plans_into_voltage.id_plan = [allocation_schematic.information].primary_infos.id)
INNER JOIN [allocation_schematic.types].plans_into_type on [allocation_schematic.types].plans_into_type.id_plan = [allocation_schematic.information].primary_infos.id )
INNER JOIN [allocation_schematic.types].voltage ON [allocation_schematic.types].voltage.id = [allocation_schematic.types].plans_into_voltage.id_voltage)
INNER JOIN [allocation_schematic.types].catenary_type ON [allocation_schematic.types].catenary_type.id = [allocation_schematic.types].plans_into_type.id_type)
INNER JOIN [allocation_schematic.information].folders ON [allocation_schematic.information].folders.id = [allocation_schematic.information].primary_infos.id_folder)
INNER JOIN [allocation_schematic.information].plans_versions ON [allocation_schematic.information].plans_versions.id_plan = [allocation_schematic.information].primary_infos.id)
INNER JOIN [allocation_schematic.information].plans_into_status ON [allocation_schematic.information].plans_into_status.id_plan = [allocation_schematic.information].primary_infos.id)
INNER JOIN [allocation_schematic.information].plans_status ON [allocation_schematic.information].plans_status.id = [allocation_schematic.information].plans_into_status.id_status)
INNER JOIN [allocation_schematic.fields].plans_into_app_field ON [allocation_schematic.fields].plans_into_app_field.id_plan = [allocation_schematic.information].primary_infos.id)
INNER JOIN [allocation_schematic.fields].application_fields ON [allocation_schematic.fields].application_fields.id = [allocation_schematic.fields].plans_into_app_field.id_field)
; |
Problème : Les lignes se dupliquent entre elles dès qu'il y a plusieurs tensions associées à un plan et/ou plusieurs types de caténaires.
Ce qui donne : 
Ma solution : Dans mon programme en c# j'ai fait un petit système de concaténation des lignes en double afin d'avoir toutes les tensions dans une seule cellule etc.. Sauf que ce traitement est très long avec seulement 20000 plans sachant qu'à l'avenir il y en aura des centaines de milliers.
Je ne sais pas si c'est approprié d'y poster ici mais voilà ce que fait mon programme :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| // Élimine les lignes dupliquées dû à plusieurs types de caténaires, domaines d''applications, tensions.. pour un plan
// Boucle sur le nombre total de lignes du datagridview
for (int x = 1; x < dgw_plans.Rows.Count; x++)
{
string dupli_detect = dgw_plans.Rows[x].Cells[0].Value.ToString(); // La chaine de caractères prend en valeur le numéro du plan de la ligne
if (dupli_detect == dgw_plans.Rows[x - 1].Cells[0].Value.ToString()) // Si la chaîne de caractères correspond à la ligne précédente on a true
{
for(int y = 0; y < dgw_plans.Columns.Count; y++) // Boucle sur le nombre total de colonnes de la lignes
{
if(dgw_plans.Rows[x].Cells[y].Value.ToString() != dgw_plans.Rows[x - 1].Cells[y].Value.ToString()) // Si la valeur de cette colonne est différente de la valeur de cette même colonne à la ligne précédente on a true ex : Type 350 STI != Type 200 STI
{
// Alors on concatène ces deux valeurs dans une string et affecte cette valeur à la colonne actuelle
string new_cell_value = dgw_plans.Rows[x].Cells[y].Value.ToString() + "; " + dgw_plans.Rows[x - 1].Cells[y].Value.ToString();
dgw_plans.Rows[x].Cells[y].Value = new_cell_value;
}
}
dgw_plans.Rows.Remove(dgw_plans.Rows[x - 1]); // On supprime ensuite la ligne de trop
x--; // Une ligne de moins ? Pour éviter d''en sauter une on retourne une ligne en arrière
}
} |
Problème de la solution : ce petit mécanisme se révèle très très long (1m50s environ) lorsqu'on a des dizaines de milliers de plans ce qui est ennuyant à chaque fois qu'on veut ouvrir le programme et puis dans mes cellules 'Tensions' et 'Type de caténaires' j'obtient au total n_tensions * n_types la même valeur...ce qui est gênant dans le programme
J'ai donc trouvé une autre solution qui pourrait éviter d'utiliser ce mécanisme : faire la concaténation dans ma requête directement.
J'ai fait un STRING_AGG sur chacune de mes colonnes ! Mais problème similaire à celui précédemment : énormément de doublons de valeurs..

Ma question est donc de savoir s'il est possible de supprimer de n'importe quelle manière directement en SQL du moment que c'est plus rapide que de faire le traitement en C#, les doublons de chaines de caractères. J'étudierais toutes les solutions proposées.
Bien évidemment j'ai cherché sur tout forum anglophone, francophone..
Merci !
Partager