Honda: MysQL - DELETE ab dem x-ten Eintrag pro ID

Hallo,

ich habe in einer MySQL-Datenbank eine Reihe von Einträgen pro ID, mit Datumsangabe.

D.h. >> ID, Eintrag, Datum

Wie gehe ich nun vor, wenn ich alle über den 10ten Eintrag (sortiert nach Datum) hinausgehenden Einträge pro ID löschen möchte?

D.h. als Resultat soll gewährleistet sein, dass pro ID stets maximal 10 Einträge vorhanden sind (sortiert nach Datum).

Vielen Dank,
Honda

  1. Hallo!

    D.h. >> ID, Eintrag, Datum

    Wie gehe ich nun vor, wenn ich alle über den 10ten Eintrag (sortiert nach Datum) hinausgehenden Einträge pro ID löschen möchte?

    D.h. als Resultat soll gewährleistet sein, dass pro ID stets maximal 10 Einträge vorhanden sind (sortiert nach Datum).

    Das ganze geht IMHO nur mit einem Subselect.

    Mit dem Subselect hole ich das Datum des 11. Eintrages mit der id=10, absteigent sortiert. Dann werden die Einträge gelöscht, die die id=10 besitzen und bei denen das Datum kleiner oder gleich ist, als das vom 11. Eintrag. Der 11. Eintrag sollte also auch mit raus fliegen.

    !!! UNGETESTET !!!

      
    DELETE  
    FROM  
      tabelle  
    WHERE  
      id = 10  
    AND  
      datum <=  
         (  
           SELECT datum FROM tabelle WHERE id = 10 ORDER BY datum DESC LIMIT 10, 1  
         );  
    
    

    André Laugks

    --
    Die Frau geht, die Hilti bleibt!
    1. Hallo André

      Wie gehe ich nun vor, wenn ich alle über den 10ten Eintrag (sortiert nach Datum) hinausgehenden Einträge pro ID löschen möchte?

      D.h. als Resultat soll gewährleistet sein, dass pro ID stets maximal 10 Einträge vorhanden sind (sortiert nach Datum).

      Das ganze geht IMHO nur mit einem Subselect.

      Nein. Da liegst Du falsch.

      Mit dem Subselect hole ich das Datum des 11. Eintrages mit der id=10, absteigent sortiert. Dann werden die Einträge gelöscht, die die id=10 besitzen und bei denen das Datum kleiner oder gleich ist, als das vom 11. Eintrag. Der 11. Eintrag sollte also auch mit raus fliegen.

      !!! UNGETESTET !!!

      und ungeeignet.

      DELETE
      FROM
        tabelle
      WHERE
        id = 10
      AND
        datum <=
           (
             SELECT datum FROM tabelle WHERE id = 10 ORDER BY datum DESC LIMIT 10, 1
           );

        
      Dummerweise haben die nächsten 5 Datensätze ebenfalls das gleiche Datum wie der 11. Eintrag. Es bleiben nur noch 5 Datensätze übrig, keine 10 wie gefordert.  
        
      Wenn schon Subselect, dann finde eine Spalte, die die 10 Datensätze, die übrig bleiben sollen genau identifiziert und verwende `WHERE ... NOT IN (SELECT ...)`{:.language-sql}.  
        
      Eine Möglichkeit ohne Subselect wäre der Einsatz von Benutzervariablen. Siehe mein [Archivposting](/archiv/2006/9/t136068/#m883458) in einem anderen Zusammenhang. Lösche die Datensätze mit Variablenwerten > 10. (Ebenfalls ungetestet!)  
        
        
      Freundliche Grüße  
        
      Vinzenz
      
      1. Moin!

        Das ganze geht IMHO nur mit einem Subselect.

        Nein. Da liegst Du falsch.

        Schön, dass die Ideen so eindeutig richtig oder falsch zu sein scheinen. :)

        DELETE
        FROM
          tabelle
        WHERE
          id = 10
        AND
          datum <=
             (
               SELECT datum FROM tabelle WHERE id = 10 ORDER BY datum DESC LIMIT 10, 1
             );

        
        >   
        > Dummerweise haben die nächsten 5 Datensätze ebenfalls das gleiche Datum wie der 11. Eintrag. Es bleiben nur noch 5 Datensätze übrig, keine 10 wie gefordert.  
          
        MySQL hat auch in Version 5.1 die Einschränkung, dass man kein Subselect auf die Tabelle machen kann, aus der man löschen will. Insofern funktioniert der Ansatz ohnehin nicht.  
          
        
        > Wenn schon Subselect, dann finde eine Spalte, die die 10 Datensätze, die übrig bleiben sollen genau identifiziert und verwende `WHERE ... NOT IN (SELECT ...)`{:.language-sql}.  
          
        Auch dein Ansatz übrigens nicht.  
          
        Aber es gibt eine recht simple Methode: DELETE kann ORDER BY und LIMIT.  
          
        Dabei ist jetzt allerdings die genaue Fragestellung zu berücksichtigen: Der OP hat gefordert, dass \_maximal\_ 10 Datensätze übrig bleiben. Damit ist die Aufgabe unterspezifiziert, denn auch 0 Datensätze wären ja \_maximal\_ 10, was die Löschaufgabe erheblich vereinfachen würde, aber aus nachvollziehbaren Gründen kaum sinnvoll erscheint.  
          
         - Sven Rautenberg
        
        -- 
        "Love your nation - respect the others."
        
        1. hi,

          Aber es gibt eine recht simple Methode: DELETE kann ORDER BY und LIMIT.

          Auch in der von SELECT "bekannten Form"?

          Wenn ich das Manual diesbezüglich richtig verstehe, kann man bei DELETE mittels LIMIT nur einen "row_count" angeben - wie viele Datensätze maximal gelöscht werden sollen. Aber einen Offset anzugeben wie bei einem SELECT, geht da nicht.

          In Kombination mit ORDER BY kann man da also problemlos sagen "lösche mir die X ältesten Datensätze".
          Aber "lösche alle bis auf die X letzten" ist damit nicht in einem simplen DELETE-Statement möglich.

          gruß,
          wahsaga

          --
          /voodoo.css:
          #GeorgeWBush { position:absolute; bottom:-6ft; }