Erstellen Sie unter bestimmten Bedingungen eine von zwei Daten

13

Zuerst muss ich alle Daten von ODBC erhalten (dies funktioniert bereits).

Dann kommt der komplizierteste Teil, bei dem ich mir noch nicht sicher bin, wie es gemacht werden kann. In ODBC gibt es zwei Datentabellen. Ich füge sie mit meinem aktuellen Code zusammen und filtere sie mit bestimmten Parametern.

Tabelle 1 in der Datenbank:

NRO   NAME   NAMEA   NAMEB   ADDRESS   POSTA   POSTN   POSTADR   COMPANYN   COUNTRY   ID  ACTIVE
123   Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
133   Opel   Meriva  FTG     J5        K4      O3      P4        O2         JO        3   1
153   MB     E200    C25     JN        KI      OP      PY        OR         JD        5   1
183   BMW    E64     SE0     JR        KE      OT      PG        OL         J8        9   1
103   Audi   S6      700     JP        KU      OU      PN        OH         J6        11  1 

Tabelle 2 in der Datenbank:

NRO   NAME   NAMEA   NAMEB   ADDRESS   POSTA   POSTN   POSTADR   COMPANYN   COUNTRY   ID  ACTIVE
423   Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
463   BMW    E64     SE0     JR        KE      OT      PG        OL         J8        9   1

Zusammengeführte Datentabelle sieht folgendermaßen aus:

NRO   NAME   NAMEA   NAMEB   ADDRESS   POSTA   POSTN   POSTADR   COMPANYN   COUNTRY   ID  ACTIVE
423   Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
463   BMW    E64     SE0     JR        KE      OT      PG        OL         J8        9   1
123   Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
133   Opel   Meriva  FTG     J5        K4      O3      P4        O2         JO        3   1
153   MB     E200    C25     JN        KI      OP      PY        OR         JD        5   1
183   BMW    E64     SE0     JR        KE      OT      PG        OL         J8        9   1
103   Audi   S6      700     JP        KU      OU      PN        OH         J6        11  1 

Die zusammengeführte Ausgabedatentabelle sollte jedoch so aussehen (um die Möglichkeit zu haben, weiter damit zu arbeiten):

NRO  NRO1   NAME   NAMEA   NAMEB   ADDRESS   POSTA   POSTN   POSTADR   COMPANYN   COUNTRY   ID  ACTIVE
123  423    Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
133         Opel   Meriva  FTG     J5        K4      O3      P4        O2         JO        3   1
153         MB     E200    C25     JN        KI      OP      PY        OR         JD        5   1
183  463    BMW    E64     SE0     JR        KE      OT      PG        OL         J8        9   1
103         Audi   S6      700     JP        KU      OU      PN        OH         J6        11  1 

Suchen Sie nach Duplikaten in NAME. Lassen Sie nur einen von ihnen, weisen Sie eine Nummer aus Tabelle 1 bis NROTabelle 2 zu NRO1. Die Nummern in Tabelle 1 sollten in sein NRO, die Nummern in Tabelle 2 sollten in sein NRO1.

Nach dem Herstellen einer Verbindung zu ODBC fülle ich eine Tabelle mit Daten aus Tabelle 1

        DataTable dataTable = new DataTable("COMPANY");

        using (OdbcConnection dbConnectionSE = new OdbcConnection(connectionStringSE))
        {
            dbConnectionSE.Open();
            OdbcDataAdapter dadapterSE = new OdbcDataAdapter();
            dadapterSE.SelectCommand = new OdbcCommand(queryStringSE, dbConnectionSE);

            dadapterSE.Fill(dataTable);

        }

dann erhalte ich Daten aus einer anderen Tabelle 2 und füge sie zusammen durch:

         using (OdbcConnection dbConnectionFI = new OdbcConnection(connectionStringFI))
         {
              dbConnectionFI.Open();
              OdbcDataAdapter dadapterFI = new OdbcDataAdapter();
              dadapterFI.SelectCommand = new OdbcCommand(queryStringFI, dbConnectionFI);

              var newTable = new DataTable("COMPANY");
              dadapterFI.Fill(newTable);

              dataTable.Merge(newTable);
          }

Danach führe ich eine Filterung durch (ich brauche Zeilen, die nur mit 4 und 1 Zoll beginnen NRO, es gibt auch Zeilen mit einer anderen Startnummer):

DataTable results = dataTable.Select("ACTIVE = '1' AND (NRO Like '1%' OR NRO Like '4%')").CopyToDataTable();

Dann füge ich eine weitere Spalte hinzu für NRO1(dies fügt auch Nullen hinzu (0) Ich brauche sie nicht in Spalte NRO1):

        results.Columns.Add("NRO1", typeof(int)).SetOrdinal(1);

        foreach (DataRow row in results.Rows)
        {
            //need to set value to NewColumn column
            row["NRO1"] = 0;   // or set it to some other value
        }

Mit diesem Code kann ich Duplikate fangen

var duplicates = results.AsEnumerable().GroupBy(r => r[2]).Where(gr => gr.Count() > 1);

aber wie soll man den Rest erledigen? Dies sollte durch eine Schleife mit dem Erstellen einer neuen Tabelle durchgeführt werden? Wie kann ich Duplikate verbinden und entfernen dataTable?

Hut Mann
quelle
1. Kann dataTablefür einen Namen mehr als zwei Duplikate enthalten? Ist es beispielsweise möglich, drei Duplikate für BMW zu existieren? 2. Wie können wir definieren, welche der doppelten Datensätze aufbewahrt und welche gelöscht werden sollen? Zum Beispiel können wir Aufzeichnungen mit einem Minimum führen NROund die anderen Aufzeichnungen löschen.
Iliar Turdushev
@IliarTurdushev 1. Die Datentabelle darf nicht mehr als ein "Duplikat" enthalten NAME. Wenn mehr als zwei - Fehler (Fehlerbehandlungsroutine). 2. In meinem Beispiel ist ein Fehler aufgetreten. Ich habe ihn jetzt behoben. Vielen Dank für die Erwähnung dieses, es ist wichtig.
Hatman
Können Sie bitte die Werte von queryStringFI und / oder queryStringSE teilen? Plus welche DB benutzt du?
ATTA
@ATTA Ich kann keinen Zugriff auf die aktuelle Datenbank gewähren. Du meinst DB-Typ? Wie es in Frage steht - ODBC
Hatman
Eigentlich mochte ich die Abfrage, mit der Daten abgerufen werden, jedoch basierend auf wenigen Annahmen, die ich als Antwort geschrieben habe. Bitte überprüfen Sie und geben Sie Ihr Feedback. Danke
ATTA

Antworten:

3

Sie können den merge()Aufruf durch eine benutzerdefinierte Methode ersetzen , die gleichzeitig das Zusammenführen und Filtern durchführt. Siehe das folgende Beispiel. Ich denke, dies ist ein besserer Ansatz als zuerst zusammenzuführen (doppelte Zeilen in die Ergebnistabelle einzufügen) und dann zu filtern (dh die doppelten Zeilen zu entfernen).

Hierbei wird davon ausgegangen, dass alle Parameter das gleiche Format haben. Die tTempTabelle wird als temporärer Speicher für den Inhalt der Tabelle verwendet, t2jedoch mit der zusätzlichen Spalte. Dadurch können die Zeilen in die Ergebnistabelle importiert werden.

Vielleicht gibt es eine elegantere Lösung, aber diese sollte wie beabsichtigt funktionieren. Bitte beachten Sie, dass ich Ihre zusätzliche Anforderung bezüglich der zulässigen Werte für weggelassen habe NRO, die Sie sicher leicht hinzufügen können.

static void merge_it(DataTable t1, DataTable t2, DataTable tResult, DataTable tTemp)
    {
        tResult.Merge(t1);
        tResult.Columns.Add("NRO1", typeof(int));

        tTemp.Merge(t2);
        tTemp.Columns.Add("NRO1", typeof(int));

        foreach (DataRow row in tTemp.Rows)
        {
            string name1 = row.Field<string>("NAME");
            string name2 = row.Field<string>("NAMEA");
            DataRow[] matches = tResult.Select($"NAME = '{name1}' AND NAMEA = '{name2}'");
            if (matches.Length > 0)
            {
                matches[0].SetField<int>("NRO1", row.Field<int>("NRO"));
            }
            else
            {
                tResult.ImportRow(row);
            }
        }

        foreach (DataRow row in tResult.Rows)
        {
            if (row["NRO1"] == DBNull.Value)
            {
                row["NRO1"] = 0;
            }
        }
    }
lzydrmr
quelle
Danke dafür! Ich glaube, ich habe etwas falsch gemacht, als ich 'DataTable' does not contain a definition for 'Merge_it' and no accessible extension method 'Merge_it' accepting a first argument of type 'DataTable' could be found (are you missing a using directive or an assembly reference?)nach dem Ersetzen dataTable.Merge(newTable);durchdataTable.Merge_it(newTable);
hatman
Sie könnten den Code in eine neue Klasse einfügen. Gib einfach class Merger {...}meinen Code ein und rufe an Merger.merge_it(...). Sie müssen jedoch die Eingabeparameter vorbereiten.
lzydrmr
... und Sie müssen usingnatürlich die fehlenden Anweisungen hinzufügen . Es ist nur ein Ausschnitt (aus einem Arbeitsprogramm).
lzydrmr
Ich bin mir nicht sicher über die Leistung von foreach gegenüber tResult.Select, was bei größeren Datentabellen sehr langsam sein kann (vorausgesetzt, tResult.Select ist O (n), und mit foreach ergibt sich ein O (n ^) 2) Ausführungszeit)
CitrusO2
2

Versuche dies:

  1. Fügen Sie das NRO1-Feld in beide Abfragen für Tabelle1 und Tabelle2 ein
  2. Setzen Sie den Standardwert 0 von NRO1 für Tabelle1 (ändern Sie queryStringSE).

    Beispiel: SELECT NRO, 0 AS NRO1, NAME, NAMEA, NAMEB, ... FROM TABLE1

  3. Setzen Sie den Standardwert 0 von NRO für Tabelle 2 (ändern Sie queryStringFI).

    Beispiel: SELECT 0 AS NRO, NRO AS NRO1, NAME, NAMEA, NAMEB, ...... FROM TABLE2

Tabelle 1 sieht folgendermaßen aus:

NRO  NRO1   NAME   NAMEA   NAMEB   ADDRESS   POSTA   POSTN   POSTADR   COMPANYN   COUNTRY   ID  ACTIVE
123   0     Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
133   0     Opel   Meriva  FTG     J5        K4      O3      P4        O2         JO        3   1

Tabelle 2 sieht folgendermaßen aus:

NRO  NRO1   NAME   NAMEA   NAMEB   ADDRESS   POSTA   POSTN   POSTADR   COMPANYN   COUNTRY   ID  ACTIVE
0    423    Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
0    463    BMW    E64     SE0     JR        KE      OT      PG        OL         J8        9   1
  1. Führen Sie Tabellen wie bisher zusammen

Fügen Sie folgende Codezeilen hinzu:

var carGroups = dataTable.AsEnumerable().GroupBy(row => new 
{
   Name = row.Field<string>("Name"),
   NameA = row.Field<string>("NAMEA"),
   NameB = row.Field<string>("NAMEB")
   //Other fields.....
});

DataTable result = dataTable.Clone();

foreach(var grp in carGroups)            
    result.Rows.Add(grp.Sum(r1 => r1.Field<int>("NRO")), grp.Sum(r2 => r2.Field<int>("NRO1")), grp.Key.Name, grp.Key.NameA, grp.Key.NameB);              
  1. Überprüfen Sie die DataTable "Ergebnis" auf gewünschte Werte
ATTA
quelle
0

Sie können denselben Spaltennamen in beiden Tabellen beibehalten, wenn sie denselben Entitätstyp bezeichnen. Dann wird dieser Code angezeigt

 private static void DemonstrateMergeTable()
{
    DataTable table1 = new DataTable("Items");

    // Add columns
    DataColumn idColumn = new DataColumn("id", typeof(System.Int32));
    DataColumn itemColumn = new DataColumn("item", typeof(System.Int32));
    table1.Columns.Add(idColumn);
    table1.Columns.Add(itemColumn);

    // Set the primary key column.
    table1.PrimaryKey = new DataColumn[] { idColumn };

    // Add RowChanged event handler for the table.
    table1.RowChanged += new 
        System.Data.DataRowChangeEventHandler(Row_Changed);

    // Add ten rows.
    DataRow row;
    for (int i = 0; i <= 9; i++)
    {
        row = table1.NewRow();
        row["id"] = i;
        row["item"] = i;
        table1.Rows.Add(row);
    }

    // Accept changes.
    table1.AcceptChanges();
    PrintValues(table1, "Original values");

    // Create a second DataTable identical to the first.
    DataTable table2 = table1.Clone();

    // Add column to the second column, so that the 
    // schemas no longer match.
    table2.Columns.Add("newColumn", typeof(System.String));

    // Add three rows. Note that the id column can't be the 
    // same as existing rows in the original table.
    row = table2.NewRow();
    row["id"] = 14;
    row["item"] = 774;
    row["newColumn"] = "new column 1";
    table2.Rows.Add(row);

    row = table2.NewRow();
    row["id"] = 12;
    row["item"] = 555;
    row["newColumn"] = "new column 2";
    table2.Rows.Add(row);

    row = table2.NewRow();
    row["id"] = 13;
    row["item"] = 665;
    row["newColumn"] = "new column 3";
    table2.Rows.Add(row);

    // Merge table2 into the table1.
    Console.WriteLine("Merging");
    table1.Merge(table2, false, MissingSchemaAction.Add);
    PrintValues(table1, "Merged With table1, schema added");
}

private static void Row_Changed(object sender, 
    DataRowChangeEventArgs e)
{
    Console.WriteLine("Row changed {0}\t{1}", e.Action, 
        e.Row.ItemArray[0]);
}

private static void PrintValues(DataTable table, string label)
{
    // Display the values in the supplied DataTable:
    Console.WriteLine(label);
    foreach (DataRow row in table.Rows)
    {
        foreach (DataColumn col in table.Columns)
        {
            Console.Write("\t " + row[col].ToString());
        }
        Console.WriteLine();
    }
}
Jin Thakur
quelle