Avatar billede nemlig Professor
14. april 2015 - 09:54 Der er 9 kommentarer og
1 løsning

Slet alle poster, bortset fra de 10000 nyeste

Hejsa.
Jeg har et script, hvor jeg i en tabel gemmer nogle måleraflæsninger hvert 15 min. Da det kun er interessant, at se de seneste 10000 aflæsninger, vil jeg gerne i mit script lave det sådan, at der hele tiden vises de 10000 seneste.

Jeg har læst mig frem til nedenstående kode, men den sletter alle poster, bortset fra de sidste 20. Jeg har auto_increment på feltet `id`

$sql = "DELETE FROM `varmestatus`
WHERE id NOT IN (
  SELECT id
  FROM (
    SELECT id
    FROM `varmestatus`
    ORDER BY id DESC
    LIMIT 10000
  ) foo
)";
Avatar billede gnoname Praktikant
14. april 2015 - 11:02 #1
Er du sikker på, at du får 10000 forskellige ID'er ud med selectet? Altså med:

SELECT id
    FROM `varmestatus`
    ORDER BY id DESC
    LIMIT 10000

Alternativt kan du f.eks. forsøge med

$sql = "DELETE FROM `varmestatus`
WHERE id <=
  ( SELECT max(id) - 10000
    FROM `varmestatus`
  )
)";

hvis du er sikker på, at du incrementerer med 1 per aflæsning.
Avatar billede nemlig Professor
14. april 2015 - 11:26 #2
#1 Nej det gør jeg ikke, idet der kun er 20 poster.
Hver 15. minut gemmes ny post, men så køres Delete-scriptet efterfølgende.

Jeg troede, at den først vil "delete", når tabeller kommer op over 10000 poster.

Tak for dit forslag til kode. Men jeg kan ikke forstå, hvis det skal virke.

Lige nu ligger der 20 poster, og hvor seneste post har id nr. 536.
Vil det virke med max(id)- 10000?

Løsningen skal gerne være, at der ikke slettes noget, så længe der er under 10.000 poster, og derefter beholdes de 10.000 nyeste (læs: højeste id-numre).
Avatar billede gnoname Praktikant
14. april 2015 - 11:37 #3
Det burde virke, idet det jo kun vil være records med ID mindre end eller lig med 536-10000 (altså id mindre end eller lig med -9464).
Avatar billede nemlig Professor
14. april 2015 - 11:48 #4
OK, det skal prøves.....
Avatar billede nemlig Professor
14. april 2015 - 11:51 #5
Hov... Opdager lige, at jeg i min online-kode havde LIMIT 20 og ikke LIMIT 10000.
Så er der jo ikke noget at sige til, at der kun er 20 poster.

Jeg prøver lige begge dele og vender tilbage.
Avatar billede nemlig Professor
14. april 2015 - 13:17 #6
#3 Jeg får denne fejl:

You can't specify target table 'varmestatus' for update in FROM clause

Jeg har i øvrigt fjernet den sidste parentes.
Avatar billede gnoname Praktikant
14. april 2015 - 13:36 #7
Du skal nok bare wrappe det ind i en subquery som i dit eget eksempel (din sql-fortolker er åbenbart meget sart :-)

$sql = "DELETE FROM `varmestatus`
WHERE id <= (
  SELECT maxid-10000
  FROM (
    SELECT max(id) maxid
    FROM `varmestatus`
  ) foo
)";
Avatar billede nemlig Professor
14. april 2015 - 14:21 #8
Så funger det. Har lige testet med "30" i stedet for 10.000. Det spiller .

Tak for input og vejledning.

Smid venligst et svar.
Avatar billede gnoname Praktikant
14. april 2015 - 14:35 #9
Det er helt fint :-)
Avatar billede arne_v Ekspert
20. april 2015 - 04:29 #10
Den loesning virker ikke hvis der opstaar huller i id.

Den oprindelige kode boer virke.

mysql> CREATE TABLE deldemo (
    ->    id INTEGER NOT NULL,
    ->    PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> INSERT INTO deldemo VALUES(1);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO deldemo VALUES(3);
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO deldemo VALUES(5);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO deldemo VALUES(7);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO deldemo VALUES(9);
Query OK, 1 row affected (0.02 sec)

mysql>
mysql> SELECT * FROM deldemo;
+----+
| id |
+----+
|  1 |
|  3 |
|  5 |
|  7 |
|  9 |
+----+
5 rows in set (0.00 sec)

mysql>
mysql> DELETE FROM deldemo
    -> WHERE id NOT IN (SELECT * FROM (SELECT id FROM deldemo ORDER BY id DESC LIMIT 3) x);
Query OK, 2 rows affected (0.01 sec)

mysql>
mysql> SELECT * FROM deldemo;
+----+
| id |
+----+
|  5 |
|  7 |
|  9 |
+----+
3 rows in set (0.00 sec)

mysql>
mysql> DELETE FROM deldemo
    -> WHERE id NOT IN (SELECT * FROM (SELECT id FROM deldemo ORDER BY id DESC LIMIT 3) x);
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> SELECT * FROM deldemo;
+----+
| id |
+----+
|  5 |
|  7 |
|  9 |
+----+
3 rows in set (0.00 sec)

mysql>
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester