7
votes

Comment comparer les valeurs de cellule de deux tables de données

Si j'ai deux tables de données avec la même structure, la même clé primaire et le même nombre de colonnes.

Comment comparer leur contenu code> et détecter les cellules qui ne sont pas identiques dans le Deux tables de données? p>

ex: p>

tb_offline strong> p> xxx pré>

tb_online forte > p> xxx pré>


Je veux obtenir un résultat comme celui-ci (ou une structure pour afficher les différences): p>

455 doesn't exist in the result because it was the exact in all columns among the two datatables.


0 commentaires

8 Réponses :


1
votes

Si c'est associé SQL, vous pouvez utiliser la commande SQL sauf SQL:

Sélectionnez * de tb_online À L'EXCEPTION Sélectionnez * à partir de tb_offline

Vous pouvez jeter un coup d'œil ici , sous" Comparer les tables à l'aide de la clause sauf "


0 commentaires

-1
votes

Dans la requête SQL, vous pouvez rejoindre deux tables et utiliser une instruction CASE-CAS pour déterminer la valeur de différence pour chaque colonne: E.G

SELECT 
TB_Online.emp_num,
TB_Online.salary_on,
TB_Offline.salary_off,
SELECT CASE TB_Online.salary_on = Tb_offline.salary_off then 0 ELSE 1 END AS salary_same
...
FROM TB_Online INNER JOIN TB_Offline
ON TB_Online.emp_num = TB_Offline.emp_num


1 commentaires

Désolé, votre réponse relative au SQL pas le .NET



3
votes

Vous pouvez obtenir toutes les clés d'abord, puis créer un nouveau (code> Résumé des objets code>, mettez les données là-bas et laissez-le faire le travail de comparaison. Enfin, vous pouvez faire ce que vous voulez avec elle: xxx pré>

Résumé code> Classe d'assistance: p>

class Summary
{
    public Summary(int emp_num, DataRow rowOff, DataRow rowOn)
    {
        this.emp_num = emp_num;

        if (rowOff != null)
        {
            salary_off = (int)rowOff["salary"];
            ov_off = (double)rowOff["ov"];
        }

        if (rowOn != null)
        {
            salary_on = (int)rowOn["salary"];
            ov_on = (double)rowOn["ov"];
        }
    }
    public int emp_num;

    public int salary_off ;
    public int salary_on;
    public bool salarySame { get { return salary_off == salary_on; }  }

    public double ov_off ;
    public double ov_on;
    public bool ovSame { get { return ov_off == ov_on; } }

}


3 commentaires

+1 Pour la réponse, merci beaucoup, mais cette méthode est limitée, j'attends une méthode générique pour faire la comparaison.


@AnyNameDonotCare qu'entendez-vous par méthode générique? Il n'y a rien à ce sujet dans votre question ;-)


J'apprécie beaucoup vos efforts :), je veux dire dans le constructeur u utilise des champs spécifiques (int) étadouffes ["salaire"] , (double) écrans ["ov"] et avec des types spécifiques. Je souhaite utiliser cette méthode avec deux datables avec n'importe quelle structure.



2
votes

Selon vous les nouvelles exigences, vous pouvez essayer ceci.

Il reçoit d'abord le nom de la clé primaire - la colonne unique code>, puis les autres noms de colonnes, crée un nouveau DataTable Code> avec de nouveaux noms de colonne, remplit les valeurs et crée une expression pour la comparer: p>

static DataTable CompareDataTables(DataTable dt1, DataTable dt2)
{
    var keyName = dt1.Columns.Cast<DataColumn>().Single (x => x.Unique).ColumnName;
    var dt1Cols = dt1.Columns.Cast<DataColumn>().Where (x => !x.Unique).Select (x =>x.ColumnName );
    var dt2Cols = dt1.Columns.Cast<DataColumn>().Where (x => !x.Unique).Select (x =>x.ColumnName );

    // get keys from both data tables
    var keys = new HashSet<int>(dt1.AsEnumerable().Select (x => (int)x[keyName]));
    keys.UnionWith(dt2.AsEnumerable().Select (x => (int)x[keyName]));

    keys.Dump("keys");

    // create a new data table that will hold the results
    var result = new DataTable();
    result.Columns.Add(keyName, typeof(int));
    result.Columns[0].Unique = true;

    // initialize data and comparison columns
    foreach (var name in dt1Cols)
    {
        result.Columns.Add(name + "_off", dt1.Columns[name].DataType);
        result.Columns.Add(name + "_on", dt1.Columns[name].DataType);
        result.Columns.Add(name + "_same", typeof(bool), name + "_off = " + name + "_on");
    } 


    foreach (var key in keys)
    {
        // get a row from each data table with the current key
        var rowOff = dt1.Select(keyName + " = " + key).FirstOrDefault();
        var rowOn = dt2.Select(keyName + " = " + key).FirstOrDefault();

        // create a new row            
        var newRow = result.NewRow();

        // fill the new row with off data
        if (rowOff != null)
        {
            newRow[keyName] = rowOff[keyName];
            foreach (var name in dt1Cols)
            {
                newRow[name + "_off"] = rowOff[name];
            }
        }

        // fill the new row with on data
        if (rowOn != null)
        {
            foreach (var name in dt1Cols)
            {
                newRow[name + "_on"] = rowOn[name];
            }
            newRow[keyName] = rowOn[keyName];
        }

        // add the row to the result data table
        result.Rows.Add(newRow);        
    }

    return result;
}


2 commentaires

Pourriez-vous clarifier ce qui est Méthode ? Est-ce un .NET ?


Oh pardon. Il s'agit de la pâte de copie à partir de linqpad et Dump est sa méthode pour vider des objets. Il a créé les grilles sur l'image pour faciliter le débogage.



3
votes

Voici un moyen d'atteindre votre tâche:

 var dt1 = new DataTable();
        dt1.Columns.Add("emp_num", typeof(int));
        dt1.Columns.Add("salary", typeof(int));
        dt1.Columns.Add("ov", typeof(double));
        dt1.Columns[0].Unique = true;

        dt1.Rows.Add(455, 3000, 67.891);
        dt1.Rows.Add(677, 6000, 50.113);
        dt1.Rows.Add(778, 5500, 12.650);
        dt1.Rows.Add(779, 5500, 12.672);

        var dt2 = new DataTable();
        dt2.Columns.Add("emp_num", typeof(int));
        dt2.Columns.Add("salary", typeof(int));
        dt2.Columns.Add("ov", typeof(double));
        dt2.Columns[0].Unique = true;

        dt2.Rows.Add(455, 3000, 67.891);
        dt2.Rows.Add(677, 5000, 50.113);
        dt2.Rows.Add(778, 5500, 12.672);
        dt2.Rows.Add(779, 5500, 12.672);

        var dtListValues1 = new List<List<string>>();



        for (int j = 0; j < dt2.Rows.Count; j++)
        {
            var list = new List<string>();
            for (var i = 0; i < dt2.Columns.Count; i++)
            {                

                    list.Add(dt2.Rows[j][i].ToString());
                list.Add("===");

                    list.Add(dt1.Rows[j][i].ToString());
                list.Add("||");
                if(dt2.Rows[j][i].ToString() == dt1.Rows[j][i].ToString())
                {
                    list.Add("true");
                }
                else
                {
                    list.Add("false");
                }

            }
            dtListValues1.Add(list);
        }

        var rowsWithDifferentCells = dtListValues1.Where(x => x.Contains("false"));


        foreach (var item in dtListValues1)
        {
            Console.WriteLine("Row-->> "+ string.Join(",",item));
        }
        Console.WriteLine("----------------------------------------");
        foreach (var item in rowsWithDifferentCells)
        {
            Console.WriteLine("Row with different cell-->> "+string.Join(",", item));
        }


0 commentaires

7
votes

Voici une implémentation dans une méthode assez générique qui compare deux datables et renvoie une autre donnée avec les différences montrées.

  • colonne "Key" dynamique (seule colonne unique, pas multiple). LI>
  • ne affiche pas les rangées qui ont les mêmes données. li>
  • traite des nulls dans les données. LI>
  • colonnes non dans les deux tables. LI>
  • t = comparaisons d'objet. Li> ul>

    peupler les datables ... strong> p> xxx pré>

     Sortie de la table de fantaisie de Linqpad de l'entrée. p>

    Méthode générique: DataTable Comparer (Datatable, Datatable) STRY> P>

    
        emp_num, salary_Pre, salary_Post, ov_Pre, ov_Post
        677, 5000, 5000, 89.112, 50.113
        778, 6000, 5500, 12.672, 12.672
        4, , 10, 9.2, 9.2
    
    


0 commentaires

1
votes

Voici mon prise sur elle: xxx


0 commentaires

0
votes