[PHP] Datensätze löschen, bis auf 50.

Axel

Butterfly
17 Juni 2006
76
1
Hallo.

Ich Hab 2 Tabellen (user und transaktionen).
Ich möchte gerne aus "transaktionen" alle Einträge eines users löschen, bis auf 50.

Habe nur grad keine Idee wie ich das anstellen soll.

Gibt es dafür vllt eine Funktion im mysql_query?
Wie würdet ihr das Problem lösen.

Damit nur die alten Datensätze gelöscht werden kann man sie an der spalte Zeit ordnen (enthält unix-timestamp).

bis jetzt sieht mein Code so aus:

PHP:
...

$abfrage = mysql_query("SELECT * FROM user");
while($row = mysql_fetch_object($abfrage))
{

  $userID = $row->id;
   			 
    $abfrage2 = mysql_query("SELECT * FROM transaktionen WHERE user = '$userID'");
    while($row2 = mysql_fetch_object($abfrage2)) {
	
	  # ??? #
	
    }

}

...

Danke schonmal im Vorraus.
 
PHP:
$anzahl = mysql_num_rows(mysql_query("SELECT DISTINCT t.COUNT(*) FROM user AS u LEFT JOIN transaktionen AS t ON (u.id = t.user)"));

 mysql_query("DELETE FROM transaktionen AS t RIGHT JOIN user AS u ON (u.id = t.user) ORDER BY Zeit DESC LIMIT ".$anzahl);

mach vorher ne Sicherheitskopie der DB ist ungetestet könnte auch nen mysql_error() geben bin nimmer so ganz fit, häng schon den ganzen tag am rechner und code. :yawn: Aber nu geht ich mal anner Matratze horchen. Gut´s Nächtle
 
Da es mit MySQL nicht wirklich effizient geht, alle bis X Datensätze zu löschen, würde ich das Ganze mittels zwei Queries lösen. Der erste liest die 50 neuesten Datensätze aus, der zweite löscht alle Datensätze bis auf die grade ausgelesenen:
PHP:
$ids = Array();

$db->query("SELECT id FROM table WHERE something = TRUE LIMIT 0,50");
while ($row = $db->fetch_array())
{
  array_push ( $ids, $row['id'] );
}
$db->release();

if ( !empty( $ids ) )
{
  $db->query("DELETE FROM table WHERE id NOT IN (".implode(',', $ids.")");
}
Ist eventuell auch über'n Subquery zu lösen, aber das darfste selbst austesten. ;)
 
Code:
$datensaetze=$db->fetch_query('SELECT COUNT(*) as anzahl FROM tabelle WHERE user=%s','ice-breaker');
$db->freeResult();
if($datensaetze['anzahl']>50){
  $limit=$datensaetze['anzahl']-49;
  $db->query('DELETE FROM tabelle WHERE user=%s LIMIT 50,%d','ice-breaker',$limit);
}

so, würde ich es jetzt mal sagen, SubQuerys gehen bei DELTE ja scheinbar noch net
 
@ice
dev.mysql.com schrieb:
The MySQL-specific LIMIT row_count option to DELETE tells the server the maximum number of rows to be deleted before control is returned to the client.
PHP:
DELETE FROM somelog WHERE user = 'jcole'
ORDER BY timestamp_column LIMIT 1;

Quelle

Und so bekommt man es doch nur für einen User und nicht für alle. Man müsste doch dadurch bei 100 User 200 Db anfragen machen. Oder steh ich grad auf dem Schlauch?
 
@ice

PHP:
DELETE FROM somelog WHERE user = 'jcole'
ORDER BY timestamp_column LIMIT 1;

Quelle

Und so bekommt man es doch nur für einen User und nicht für alle. Man müsste doch dadurch bei 100 User 200 Db anfragen machen. Oder steh ich grad auf dem Schlauch?

ähm, mein Teil war totaler Quatsch, ich glaube ich sollte mich doch wieder hinsetzen und für Klausur lernen, nen Limit mit start- und Endpunkt bei Delete oO
neija nimm dann den Code von tleilax, der ist gut. Wenn man es geschickt anstellt kann man dann für alle User diese Lösung in nur 2-3 Querys durchführen
 
wieso willst du den user auch nur immer 50 transaktionen zeigen? wäre es nicht besser nach der zeit zu gehen... zb nur transaktionen aufheben die jünger als 90 tage sind? das ist mit einem query für alle user gelöst... und hat den vorteil das du keine daten aufhebst die von anno dazu mal waren.

ansonsten wenn ich immer konstant 50 datensätze aufheben wollte würde ich dies "live" lösen. sprich bei jedem hinzufügen eins raus... das kannst einmal client seitig lösen.
PHP:
myql_query("SELECT @id = MIN(id) FROM transaktioen WHERE user_id = 'xxx'; DELETE FROM transaktionen WHERE id = @id");
oder gleich server seitig (in der datenbank) per trigger... (erst ab mysql 5.0)

PHP:
CREATE TRIGGER autodel BEFORE INSERT ON transaktionen
  FOR EACH ROW BEGIN
    SELECT @id = MIN(id) FROM transaktioen WHERE user_id = NEW.user_id;
    DELETE FROM transaktionen WHERE id = @id;
  END;
(ist nen bsp... da würde noch ne überprüfung fehlen ob schon 50 datensätze da sind)
 
in mysql_query() ist aber nur ein Query möglich, 2 Stück geht erst mit mysqli und multi_query ;)
Aber Trigger ist natürlich auch ne gute Möglichkeit, sehr elegante Lösung.
 
Habs mir jetzt ganz einfach gemacht.

PHP:
# (user while)

# ...

$abfrage = mysql_query("SELECT * FROM transaktionen WHERE user = '$userID'");
  
$count = mysql_num_rows($abfrage);
  
if($count > 50) {
  
$num_delete = $count-50;
  
$query = "DELETE FROM transaktionen WHERE user = '$userID' ORDER by id ASC LIMIT $num_delete";
mysql_query($query) or die(mysql_error());
  
}

# ...

# (user while ende)

Aber trotzdem vielen Dank für eure Hilfe, habw ieder viel gelernt beim anschauen von euren Sachen!
 
@Axel:
Wieso SELECT * über alle Datensätze, wenn du eh nur an der Zeilenanzahl interessiert bist ? :hö:

Benutz wenn, dann SELECT COUNT(*), dafür gibt es das ja.