Alles bis auf 3 löschen in einem SQL-Befehl

Hi. Ich habe eine Tabelle, in der Versionen eines Textes nach dem Datum
gespeichert werden:

create table texte
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
version DATETIME,
txt TEXT
);

Nun möchte ich z.B. alle Texte bis auf die 3 aktuellsten löschen. Bsp:
+----+---------------------+----------+
| id | version | txt |
+----+---------------------+----------+
| 1 | 2007-04-28 10:53:13 | Es geht! |
| 2 | 2007-04-28 10:53:15 | Es geht! |
| 3 | 2007-04-28 10:53:17 | Es geht! |
| 4 | 2007-04-28 10:53:19 | Es geht! |
| 5 | 2007-04-28 10:53:21 | Es geht! |
+----+---------------------+----------+

delete from texte order by version limit 2;

Das funktioniert, jedoch muß ich (um auf das "limit 2" zu kommen) vorher
einen COUNT über die Tabelle machen:
5 Stück, 3 sollen übrig bleiben -> limit 2

Kriege ich das auch in EINEM SQL-Statement hin?

Viele Grüße

Martin
Martin Schneider [ Sa, 28 April 2007 10:56 ] [ ID #1700082 ]

Re: Alles bis auf 3 löschen in einem SQL-Befehl

Martin Schneider wrote:
> Hi. Ich habe eine Tabelle, in der Versionen eines Textes nach dem Datum
> gespeichert werden:
>
> create table texte
> (
> id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
> version DATETIME,
> txt TEXT
> );
>
> Nun möchte ich z.B. alle Texte bis auf die 3 aktuellsten löschen. Bsp:
> +----+---------------------+----------+
> | id | version | txt |
> +----+---------------------+----------+
> | 1 | 2007-04-28 10:53:13 | Es geht! |
> | 2 | 2007-04-28 10:53:15 | Es geht! |
> | 3 | 2007-04-28 10:53:17 | Es geht! |
> | 4 | 2007-04-28 10:53:19 | Es geht! |
> | 5 | 2007-04-28 10:53:21 | Es geht! |
> +----+---------------------+----------+
>
> delete from texte order by version limit 2;
>
> Das funktioniert, jedoch muß ich (um auf das "limit 2" zu kommen) vorher
> einen COUNT über die Tabelle machen:
> 5 Stück, 3 sollen übrig bleiben -> limit 2
>
> Kriege ich das auch in EINEM SQL-Statement hin?

Ich hab's nicht ausprobiert, aber:

Du möchtest alle Datensätze löschen, zu denen noch (irgendwelche) drei
größere `version` existieren.

DELETE a FROM texte a
INNER JOIN texte b ON b.version > a.version
INNER JOIN texte c on c.version > b.version
INNER JOIN texte d ON d.version > c.version

*Aber* Das ist ein 4-fach JOIN über die gleiche Tabelle, vermutlich ist
das Zählen und anschließende Löschen bis auf eine Anzahl schneller.

Grüße
Kai

--
This signature is left as an exercise for the reader.
Kai Ruhnau [ Sa, 28 April 2007 11:26 ] [ ID #1700084 ]

Re: Alles bis auf 3 löschen in einem SQL-Befehl

Hi Kai, danke für Deine Antwort!

> Martin Schneider wrote:
>> delete from texte order by version limit 2;
>>
>> Das funktioniert, jedoch muß ich (um auf das "limit 2" zu kommen)
>> vorher einen COUNT über die Tabelle machen:
>> 5 Stück, 3 sollen übrig bleiben -> limit 2
>>
>> Kriege ich das auch in EINEM SQL-Statement hin?
>
> Ich hab's nicht ausprobiert, aber:
>
> Du möchtest alle Datensätze löschen, zu denen noch (irgendwelche) drei
> größere `version` existieren.
>
> DELETE a FROM texte a
> INNER JOIN texte b ON b.version > a.version
> INNER JOIN texte c on c.version > b.version
> INNER JOIN texte d ON d.version > c.version
>
> *Aber* Das ist ein 4-fach JOIN über die gleiche Tabelle, vermutlich ist
> das Zählen und anschließende Löschen bis auf eine Anzahl schneller.
Okay, ich sehe das Problem ;-) Ich dachte, es gäbe in SQL was Ähnliches
wie man es z.B. in php mit substr anstellen kann, dass man mit negativen
Zahlen von hinten "losrennt", also sowas wie:
delete from texte order by version limit -3;

Aber da ist das Count vorher wohl wirklich einfacher.

Viele Grüße

Martin
Martin Schneider [ Sa, 28 April 2007 11:33 ] [ ID #1700086 ]

Re: Alles bis auf 3 löschen in einem SQL-Befehl

On Sat, 28 Apr 2007 11:33:31 +0200, Martin Schneider
<cangoou [at] yahoo.de> wrote:

>Hi Kai, danke für Deine Antwort!
>
>> Martin Schneider wrote:
>>> delete from texte order by version limit 2;
>>>
>>> Das funktioniert, jedoch muß ich (um auf das "limit 2" zu kommen)
>>> vorher einen COUNT über die Tabelle machen:
>>> 5 Stück, 3 sollen übrig bleiben -> limit 2
wie wäre es damit?

DELETE FROM texte a
WHERE a.id NOT IN (SELECT id FROM Texte ORDER BY id DESC LIMIT 3);



cu Stephan
Stephan Menzel [ Sa, 28 April 2007 12:04 ] [ ID #1700088 ]

Re: Alles bis auf 3 löschen in einem SQL-Befehl

Hi Stephan,
> On Sat, 28 Apr 2007 11:33:31 +0200, Martin Schneider
> <cangoou [at] yahoo.de> wrote:
>
>> Hi Kai, danke für Deine Antwort!
>>
>>> Martin Schneider wrote:
>>>> delete from texte order by version limit 2;
>>>>
>>>> Das funktioniert, jedoch muß ich (um auf das "limit 2" zu kommen)
>>>> vorher einen COUNT über die Tabelle machen:
>>>> 5 Stück, 3 sollen übrig bleiben -> limit 2
> wie wäre es damit?
>
> DELETE FROM texte a
> WHERE a.id NOT IN (SELECT id FROM Texte ORDER BY id DESC LIMIT 3);
Auch ne gute Idee! Leider muß ich dann meinen Provider endlich mal
dazubekommen, von MySQL 4.0.x upzudaten (ja, ich weiß...).

Viele Grüße

Martin
Martin Schneider [ Sa, 28 April 2007 17:23 ] [ ID #1700091 ]
Datenbanken » de.comp.datenbanken.mysql » Alles bis auf 3 löschen in einem SQL-Befehl

Vorheriges Thema: Stetiges Löschen und wieder Auffüllen einer Tabelle
Nächstes Thema: Auftragsboard