1. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

doppelte identische Zeilen löschen

Dieses Thema im Forum "PostgreSQL" wurde erstellt von MaCo1, 12 April 2019.

  1. MaCo1

    MaCo1 Benutzer

    Hallo zusammen,

    vorab die Info, dass ich eher Anfänger als sonst was bin auf dem Gebiet DB und SQL.

    Hier mein Problem:
    Ich habe eine DB in der alle Daten 8 mal identisch sind. Ich möchte dementsprechend 7 Zeilen löschen.
    Identisch heisst dann natürlich auch, dass die ID 8 mal gleich ist.

    Ich kann eine neue Spalte erzeugen, die die sortierten ID´s durchnummeriert, jedoch bekomme ich das nicht zusammengebaut.

    Beispiel:
    DELETE FROM "name_db"
    WHERE id IN (SELECT id, ROW_NUMBER() OVER (partition BY "alle Spalten auflisten" ORDER BY id) AS rnum
    FROM "name_db";) t
    WHERE t.rnum > 1);

    Hier löscht der mir alle Zeilen.
    Eine Lösung wäre doch, wenn:
    DELETE FROM "name_db"
    WHERE rnum .....

    Aber hier fehlt mir das Verständnis um das umzusetzen.
    Ich hoffe ihr versteht wo mein Problem liegt.

    Vielen Dank vorab.

    Gruß
    Maco
     
  2. castorp

    castorp Datenbank-Guru

    Unter der Annahme, dass ID eindeutig ist, geht das viel einfacher:

    Code:
    DELETE FROM table_name
    WHERE id NOT IN (SELECT max(t2.id)
                     from table_name t2
                     group by column_1, column_2, ...)
    alternativ (möglicherweise schneller)

    Code:
    DELETE FROM table_name d
    USING (
         SELECT min(id) as min_id, column_1, column_2 ...
         FROM table_name
         GROUP BY column_1, column_2 ...
    ) keep
    WHERE (keep.column_1, keep.column_2, ...) = (d.column_1, d.column_2, ...)
      AND keep.min_id <> d.id
    oder

    Code:
    DELETE FROM table_name a
    WHERE EXISTS (SELECT 1
                  FROM  table_name b
                  WHERE (a.column_1, a.column_2, ...) = (b.column_1, b.column_2, ...)
                    AND b.id > a.id);
     
    Walter gefällt das.
  3. MaCo1

    MaCo1 Benutzer

    Vielen Dank erstmal für deine Antwort.

    Ich befürchte, wenn ich das richtig verstehe, dass genau hier das Problem liegt.
    Jede ID ist 8 mal vorhanden und es gibt eben nichts eindeutiges.
     
    Zuletzt bearbeitet: 12 April 2019
  4. akretschmer

    akretschmer Datenbank-Guru

    Du kannst die CTID nutzen:

    Code:
    test=*# select * from maco1 ;
     id
    ----
      1
      1
      1
      1
      1
      2
      2
      2
      2
      2
      3
      3
      3
      3
    (14 rows)
    test=*# with keep as (select distinct on(id) id, ctid from maco1 ) delete from maco1 where ctid not in (select  ctid from keep);
    DELETE 11
    test=*# select * from maco1 ;
     id
    ----
      1
      2
      3
    (3 rows)
    
    test=*#
    
     
    Walter gefällt das.
  5. MaCo1

    MaCo1 Benutzer

    Guten Morgen akretschmer,

    vielen Dank!
    Habe es sofort getestet und das klappt perfekt! :)
    Einen angenehmen Wochenstart!

    Gruß
    Maco
     
    akretschmer gefällt das.
  6. akretschmer

    akretschmer Datenbank-Guru

    Das ist halt ein Trick, diese CTID-Spalte wird durch die DB selber vergeben, neben weiteren Spalten (XMIN, XMAX) und somit nur ein Implementierungsdetail, was hier ausgenutzt wird. Tabellen sollten generell mit einer explizieten Primary Key - Spalte erstellt werden, das wäre sauberer.
     
  7. MaCo1

    MaCo1 Benutzer

    Ja das habe ich schon gehört. Das war hier aber leider nicht so. Also jede Tabelle hat diese "unsichtbare" CTID-Spalte?
    Jetzt ist mir noch eine neue Sache aufgefallen.
    Die Tabelle hat 29384 Zeilen
    select distinct * from tabelle --> 3673 Zeilen

    29384 : 8 = 3673

    Würde also passen. Nach deiner Abfrage bleiben jedoch lediglich 3648 Zeilen.
    Das verstehe ich nicht.
    Hast dun da eine Idee?
     
  8. akretschmer

    akretschmer Datenbank-Guru

  9. MaCo1

    MaCo1 Benutzer

    Dann dürfte die distinct Abfrage nicht genau 1/8 der Zeilen zurückgeben. Das tut sie aber.
    Danke für den Link. Genau sowas habe ich gesucht.
    Ich versuche mich mal weiter daran. Vielen Dank für deine Mühen.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden