Portál AbcLinuxu, 9. května 2025 00:57
VARCHAR username TEXT msg DATE created_atA potreboval bych odmazat zpravy starsi nez 1 mesic, ale ponechat alespon 3 posledni pro kazdy username (i kdyz budou treba starsi nez 1 mesic) Verim, ze uz to nekdo musel resit, ale asi se googlu spatne ptam :( Dekuji
DELETE starsi nez mesic EXCEPT (SELECT prvni tri starsi nez mesic pro kazdeho usera);
CREATE TABLE msg_log ( username VARCHAR(100) , msg TEXT(100) , created_at DATE ); CREATE INDEX idx_msg_log_created_at ON msg_log (username, created_at); INSERT INTO msg_log VALUES ('y', 'A', CURRENT_DATE - interval 6 month); INSERT INTO msg_log VALUES ('x', 'B', CURRENT_DATE - interval 5 month); INSERT INTO msg_log VALUES ('x', 'C', CURRENT_DATE - interval 4 month); INSERT INTO msg_log VALUES ('x', 'D', CURRENT_DATE - interval 4 month); INSERT INTO msg_log VALUES ('x', 'E', CURRENT_DATE - interval 4 month); INSERT INTO msg_log VALUES ('x', 'F', CURRENT_DATE - interval 3 month); INSERT INTO msg_log VALUES ('x', 'G', CURRENT_DATE - interval 2 month); INSERT INTO msg_log VALUES ('x', 'H', CURRENT_DATE - interval 1 month); INSERT INTO msg_log VALUES ('x', 'I', CURRENT_DATE - interval 1 day); INSERT INTO msg_log VALUES ('y', 'J', CURRENT_DATE); INSERT INTO msg_log VALUES ('z', 'K', CURRENT_DATE - interval 10 month); INSERT INTO msg_log VALUES ('z', 'L', CURRENT_DATE - interval 9 month); INSERT INTO msg_log VALUES ('z', 'M', CURRENT_DATE - interval 8 month); INSERT INTO msg_log VALUES ('z', 'N', CURRENT_DATE - interval 7 month); INSERT INTO msg_log VALUES ('z', 'O', CURRENT_DATE - interval 6 month); INSERT INTO msg_log VALUES ('z', 'P', CURRENT_DATE - interval 3 month); DELETE d FROM msg_log AS d WHERE d.username = 'z' AND d.created_at < ( SELECT min(x.created_at) min_ts FROM ( SELECT * FROM msg_log l WHERE l.created_at < CURRENT_DATE - interval 1 month AND l.username = 'z' ORDER BY l.created_at DESC LIMIT 3 ) x) ;...a volat to pre kazdeho usera zvlast (v priklade 'z'). tu je kompletny priklad pre PostgreSQL (testovane na 12.6):
CREATE TABLE msg_log ( username VARCHAR , msg TEXT , created_at DATE ; CREATE INDEX idx_msg_log_created_at ON msg_log (username, created_at); INSERT INTO msg_log VALUES ('y', 'A', current_date - interval '6 month'); INSERT INTO msg_log VALUES ('x', 'B', current_date - interval '5 month'); INSERT INTO msg_log VALUES ('x', 'C', current_date - interval '4 month'); INSERT INTO msg_log VALUES ('x', 'D', current_date - interval '4 month'); INSERT INTO msg_log VALUES ('x', 'E', current_date - interval '4 month'); INSERT INTO msg_log VALUES ('x', 'F', current_date - interval '3 month'); INSERT INTO msg_log VALUES ('x', 'G', current_date - interval '2 month'); INSERT INTO msg_log VALUES ('x', 'H', current_date - interval '1 month'); INSERT INTO msg_log VALUES ('x', 'I', current_date - interval '1 day'); INSERT INTO msg_log VALUES ('y', 'J', current_date); INSERT INTO msg_log VALUES ('z', 'K', current_date - interval '10 month'); INSERT INTO msg_log VALUES ('z', 'L', current_date - interval '9 month'); INSERT INTO msg_log VALUES ('z', 'M', current_date - interval '8 month'); INSERT INTO msg_log VALUES ('z', 'N', current_date - interval '7 month'); INSERT INTO msg_log VALUES ('z', 'O', current_date - interval '6 month'); INSERT INTO msg_log VALUES ('z', 'P', current_date - interval '3 month'); WITH users AS ( -- idealne mat ulozene v tabulke, na ktoru odkazuje cudzi kluc na msg_log(username) SELECT DISTINCT username FROM msg_log ), maxDateKeptPerUser AS ( SELECT u.username, ( SELECT min(x.created_at) FROM (SELECT * FROM msg_log l WHERE l.created_at < CURRENT_DATE - interval '1 month' AND l.username = u.username ORDER BY l.created_at DESC LIMIT 3 ) x ) AS created_at FROM users AS u ) DELETE FROM msg_log AS d USING maxDateKeptPerUser AS m WHERE d.username = m.username AND d.created_at < m.created_at ;
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.