none
Doppelte Datensätze entfernen RRS feed

  • Frage


  • Hallo,

    ich möchte gerne doppelte Datensätze aus meiner Tabelle löschen.
    Der nahfolgende Code gibt mir zwar die Duplikate zurück, aber um
    jeweils einen oder mehrere davon löchen zu können, benötige ich
    die ID des jeweiligen Datensatzes.

    Wie kann ich die ID in den Code einbringen, so dass mir weiterhin
    Duplikate zurück gegeben werden?



    Dim 

    Duplikate = From Duplikat In db.Gesamtumsatz _
              Group Duplikat By Duplikat.Valutadatum, Duplikat.Buchungstext, Duplikat.Verwendungszweck,  _
                        Duplikat.Begnstigter_Zahlungspflichtiger, _ Duplikat.Kontonummer, Duplikat.BLZ, Duplikat.Betrag _
              Into Doppelte = Group _
    Select ANZ = Doppelte.Count(), Valutadatum, Buchungstext, Verwendungszweck, _
              Begnstigter_Zahlungspflichtiger, Kontonummer, BLZ, Betrag _
    Where ANZ > 1


    Für Eure Hilfe wäre ich dankbar!

    Steffen
    • Bearbeitet Steffen01 Montag, 13. Juli 2009 17:48 Korrektur "DIM"
    Montag, 13. Juli 2009 14:09

Antworten

  • Hallo Elmar,

    so schön Linq fürs Abfragen ist, so umständlich wird es bei solchen Aufgaben....

    Zu dieser Einsicht bin ich nach etlichen Überlegungen auch gekommen:


    Dim

    Duplikate1 = From Duplikat In db.Gesamtumsatz, Duplikat2 In Duplikate _
    Where CStr(Duplikat.Valutadatum) = CStr(Duplikat2.Valutadatum) _
    And CStr(Duplikat.Buchungstext) = CStr(Duplikat2.Buchungstext) _
    And CStr(Duplikat.Verwendungszweck) = CStr(Duplikat2.Verwendungszweck) _
    Select Duplikat.ID, Duplikat.Valutadatum

    Somit habe ich alle Duplikate, einschließlich ID, aber das von Dir eingesetze "MIN" bzw. "MAX" oder
    auch "FIRST", "LAST" läßt sich nicht ohne weiteres unterbringen.

    Dein Lösungsvorschlag ist mir bekannt, trotzdem ganz herzlichen Dank für Deine Mühe!


    Gruß

    Steffen
    • Als Antwort markiert Steffen01 Donnerstag, 16. Juli 2009 10:51
    Mittwoch, 15. Juli 2009 11:39

Alle Antworten

  • Hallo Steffen,

    so schön Linq fürs Abfragen ist, so umständlich wird es bei solchen Aufgaben.
    Duplikate löscht Du besser direkt über eine SQL Abfrage, das geht deutlich schneller.

    Für oben könnte das in etwa aussehen:
    DELETE FROM Gesamtumsatz 
    WHERE ID IN (SELECT MIN(ID) 
        FROM Gesamtumsatz
     GROUP BY Valutadatum, Buchungstext, Verwendungszweck -- ... weitere eindeutige Spalten ... HAVING COUNT(*) > 1)
    wobei ID hier für den Primärschlüssel steht.
    Ob Du den kleinsten oder größten Wert - wäre dann MAX(ID) - beibehalten willst, mußt Du anhand Deiner Daten entscheiden.

    Gruß Elmar
    Mittwoch, 15. Juli 2009 09:28
  • Hallo Elmar,

    so schön Linq fürs Abfragen ist, so umständlich wird es bei solchen Aufgaben....

    Zu dieser Einsicht bin ich nach etlichen Überlegungen auch gekommen:


    Dim

    Duplikate1 = From Duplikat In db.Gesamtumsatz, Duplikat2 In Duplikate _
    Where CStr(Duplikat.Valutadatum) = CStr(Duplikat2.Valutadatum) _
    And CStr(Duplikat.Buchungstext) = CStr(Duplikat2.Buchungstext) _
    And CStr(Duplikat.Verwendungszweck) = CStr(Duplikat2.Verwendungszweck) _
    Select Duplikat.ID, Duplikat.Valutadatum

    Somit habe ich alle Duplikate, einschließlich ID, aber das von Dir eingesetze "MIN" bzw. "MAX" oder
    auch "FIRST", "LAST" läßt sich nicht ohne weiteres unterbringen.

    Dein Lösungsvorschlag ist mir bekannt, trotzdem ganz herzlichen Dank für Deine Mühe!


    Gruß

    Steffen
    • Als Antwort markiert Steffen01 Donnerstag, 16. Juli 2009 10:51
    Mittwoch, 15. Juli 2009 11:39
  • Hallo Steffen,

    Aus Deinem LINQ Ausdruck wird nicht klar, woher die "Duplikate" stammen -
    eine vorherige Abfrage? - und wozu Du das ValutaDatum benötigst.

    Grundsätzlich wäre Dein Konstrukt mit einem INNER JOIN vergleichbar
    und das schon gezeigte SQL lässt leicht erweitern.

    Solange ValutaDatum in der GROUP BY Klausel steht:
      
    SELECT ValutaDatum, MIN(ID) AS MinID
        FROM Gesamtumsatz<br/>
        GROUP BY Valutadatum, Buchungstext, Verwendungszweck -- ... weitere eindeutige Spalten ...
        HAVING COUNT(*) > 1

    ansonsten auch via abgeleitete Tabelle:
    SELECT gu.ID, gu.ValutaDatum
    FROM Gesamtumsatz AS gu
    INNER JOIN (SELECT MIN(ID) AS MinID
        FROM Gesamtumsatz<br/>
        GROUP BY Valutadatum, Buchungstext, Verwendungszweck -- ... weitere eindeutige Spalten ...
        HAVING COUNT(*) > 1) AS gm
        ON gu.ID = gm.ID
    
    Gruß Elmar
    Donnerstag, 16. Juli 2009 08:05