Löschabfrage läuft nicht (MySQL)

katsud

Neuer Benutzer
Beiträge
3
Liebes Forum,

Ich kämpfe mit einer recht simplen Abfrage herum. Die dahinter liegende Idee ist, dass ich in einer Tabelle nur dann einen bestimmten Satz löschen möchte, wenn in der Tabelle mehr als 5 Sätze gespeichert sind. Meine Befehls-Kette dazu lautet:

use test;
set @A1 = count(Watt) from sunny;
if @A1 > 5 delete from sunny where Volt = 100;
end if;
exit;

Ich habe auch schon etliche Varianten probiert (CASE statt IF, genestetes SELECT statt Nutzung der Variable, usw).

Die Tabelle selbst ist sehr simpel und hat nur 5 Felder, sie wird (wenn die Sonne scheint) alle 30 Sekunden um einen Satz ergänzt, bis sie am Abend nach Sonnenuntergang wieder gelöscht wird.

In allen Fällen bekomme ich einen angeblichen Syntax-Fehler:

ERROR 1064(42000): You have an error in your SQL syntax;check the
manual that corresponds to your MySQL server version for the right
syntax touse near 'if @A1 > 5 delete from sunny where Volt = 100;'

Hat einer von Euch eine Idee? Ich bin am Verzweifeln...:(
 
Werbung:
Etwa so:

Code:
test=# create table sonne(id serial primary key, val numeric);
CREATE TABLE
test=*# insert into sonne (val) select random() from generate_series(1, 20) s;
INSERT 0 20
test=*# select * from sonne;
 id |  val   
----+--------------------
  1 |  0.475451360922307
  2 |  0.403788000810891
  3 |  0.158836565446109
  4 |  0.073771501891315
  5 |  0.944254070520401
  6 |  0.183132344856858
  7 |  0.713468547910452
  8 |  0.559410677757114
  9 |  0.436441907193512
 10 |  0.323474059347063
 11 |  0.234993291087449
 12 |  0.963961934670806
 13 |  0.581174960359931
 14 |  0.704448994714767
 15 | 0.0845896941609681
 16 |  0.253137807827443
 17 |  0.948370491154492
 18 |  0.721980121452361
 19 |  0.27728898730129
 20 |  0.521548673976213
(20 Zeilen)

test=*# with d as (select id, row_number() over (order by id) from sonne where val > 0.5) delete from sonne where id in (select id from d where row_number > 5);
DELETE 4

test=*# select * from sonne;
 id |  val   
----+--------------------
  1 |  0.475451360922307
  2 |  0.403788000810891
  3 |  0.158836565446109
  4 |  0.073771501891315
  5 |  0.944254070520401
  6 |  0.183132344856858
  7 |  0.713468547910452
  8 |  0.559410677757114
  9 |  0.436441907193512
 10 |  0.323474059347063
 11 |  0.234993291087449
 12 |  0.963961934670806
 13 |  0.581174960359931
 15 | 0.0845896941609681
 16 |  0.253137807827443
 19 |  0.27728898730129
(16 Zeilen)

Damit sind nun nur noch 5 mit val > 0.5 in der Tabelle, und zwar die 5 ältesten.

Du solltest genauer spezifizieren, welche Datensätze zu löschen sind, das geht aus Deiner Beschreibung nicht hervor. Das gezeigte SQL ist PostgreSQL, das an MySQL anzupassen überlasse ich Dir zur Übung.
 
Vielen Dank für die superschnelle Antwort. Es geht nicht um die Inhalte der Felder, sondern nur darum, ob mehr als 5 Sätze in der Tabelle sind
Die Tabellendefinition sieht so aus:
upload_2017-12-11_11-54-12.png
Es gibt genau einen Satz in der Tabelle, der im Feld "Volt" den Wert 100 hat. Diesen Satz erstelle ich morgens aus einer Anwendung heraus. Dieser Satz ist überflüssig, falls in der Tabelle mehr als 5 Sätze gespeichert sind; er muss aber erhalten bleiben, wenn im Lauf des Tages kein weiterer Satz erstellt wurde, damit die abendliche Auswertung (es geht um ein Solarpanel) wenigstens zu einem Ergebnis kommen kann...
Ich hoffe, ich habe das Problem jetzt besser beschrieben.
 
Werbung:
kein Ding:

angenommen, weniger als 5 Rows:

Code:
test=*# delete from sonne;
DELETE 16
test=*#
test=*#
test=*# select * from sonne;
 id | val
----+-----
(0 Zeilen)

test=*# insert into sonne(val) values (100);
INSERT 0 1
test=*# insert into sonne (val) select random() from generate_series(1, 3) s;
INSERT 0 3
test=*# with x as (select *, row_number() over (order by id desc) from ((select * from sonne where val != 100 limit 5) union all (select * from sonne where val = 100)) foo) delete from sonne where id = (select id from x where row_number = 6);
DELETE 0

Und nun mehr als 5:

Code:
test=*# insert into sonne(val) values (100);INSERT 0 1
test=*# insert into sonne (val) select random() from generate_series(1, 10) s;INSERT 0 10
test=*# with x as (select *, row_number() over (order by id desc) from ((select * from sonne where val != 100 limit 5) union all (select * from sonne where val = 100)) foo) delete from sonne where id = (select id from x where row_number = 6);
DELETE 1
test=*# select * from sonne; id |  val   
----+-------------------
 37 | 0.278165246360004
 38 | 0.790857424493879
 39 | 0.800513360649347
 40 | 0.461297591216862
 41 | 0.504325972404331
 42 | 0.359924038406461
 43 | 0.897739498410374
 44 | 0.827800031751394
 45 | 0.594917329959571
 46 | 0.861701433546841
(10 Zeilen)

test=*#

Statt meiner ID-Spalte kannst Du Deine TagUhr - Spalte nehmen. Oder könntest, wenn diese im richtigen Datenformat wäre. Ein PK wäre natürlich 'nice to have'.

Ach ja: wieder mit PostgreSQL, das an MySQL anzupassen wieder als Fingerübung für Dich.
 
Zurück
Oben