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

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

am 28.04.2007 10:56:54 von Martin Schneider

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

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

am 28.04.2007 11:26:02 von Kai Ruhnau

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.

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

am 28.04.2007 11:33:31 von Martin Schneider

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

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

am 28.04.2007 12:04:38 von Stephan Menzel

On Sat, 28 Apr 2007 11:33:31 +0200, Martin Schneider
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

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

am 28.04.2007 17:23:53 von Martin Schneider

Hi Stephan,
> On Sat, 28 Apr 2007 11:33:31 +0200, Martin Schneider
> 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