[英]How to delete record from table if its count > 5
我有下表:
id systemid value
1 1 0
2 1 1
3 1 3
4 1 4
6 1 9
8 1 10
9 1 11
10 1 12
現在在這里,我有8條systemid = 1
記錄,所以現在我只想保留最新的3條記錄(降序)並刪除systemid=1
舊記錄
我想要像這樣的輸出:
id systemid value
8 1 10
9 1 11
10 1 12
我只想刪除systemid = 1的舊記錄,前提是其計數> 5並保留其最新的3條記錄。
如何在查詢中執行此操作?
如果您並不總是有8條記錄,並且想要從表中選擇最后3條記錄(其中systemid = 1,但是有很多記錄),那么執行此操作的一種好方法是在SQL語句中使用IN選擇器。
很好,您可以使用語句簡單地做到這一點
SELECT * FROM mytable WHERE id IN (SELECT id FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3)
但是,MySQL尚不支持此功能,如果嘗試此操作,則會出現類似以下錯誤
...doesn't yet support 'LIMIT & IN/ALL/SOME subquery'
因此,您需要以下解決方法(使用SELECT進行測試):
SET @myvar := (SELECT GROUP_CONCAT(id SEPARATOR ',') AS myval FROM (SELECT * FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3 ) A GROUP BY A.systemid);
SELECT * FROM mytable WHERE FIND_IN_SET(id,@myvar);
它的工作方式(第一行)是設置一個名為@myvar的變量,如果id值,它將保留最后3個值作為逗號分隔的字符串。 就你而言
9,8,10
然后選擇該字符串中“ id”所在的行。
將“ SELECT *”替換為“ DELETE FROM”以最終確定結果,以便您進行查詢
SET @myvar := (SELECT GROUP_CONCAT(id SEPARATOR ',') AS myval FROM (SELECT * FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3 ) A GROUP BY A.systemid);
DELETE FROM mytable WHERE NOT FIND_IN_SET(id,@myvar);
我希望這個對你有用。
這將是一個很長的查詢。 您需要的是每個要刪除的記錄少於5條且排名少於3的system_id。
我將分開查詢,並在最后使用名稱。
1_ranking_query:縮寫是RQ
在mysql中,沒有rownum或類似的東西希望此查詢返回從第一個到最后一個排序的記錄。
SELECT
@rank := @rank + 1 as rank,
id,
system_id,
value
FROM table_name, (select @rank:=0) as rt
order by system_id, value desc
這將對表中的每條記錄進行排名,主要好處是具有相同system_id的記錄將按desc順序排在后面
system_id value rank
1. 10. 1
1. 9. 2
1. 7. 3
1. 5. 4
1. 3. 5
1. 2. 6
2. 12. 7
2. 10. 8
3. 11. 9
........
......
3. 1. 15
在此示例中,對於system_id 1,我們只需要為system_id 3(9,10,11)保留前三個記錄(1,2,3)記錄相同的內容
2_ filter_query。 派生為:FQ因為您要基於計數5進行刪除,所以我們需要此額外查詢
SELECT
system_id
FROM table_name
GROUP BY system_id
having count(*) > 5
結果:
system_id
1
3
4_ third_query縮寫:RQD
一個查詢,我們應該從MySQL中的每個system_id開始刪除哪個等級,我們需要再次重寫第一個查詢,但是在這里,我將使用“派生”來使答案簡短。
SELECT
system_id,
min_rank + 3 from_rank
FROM (
SELECT
RQ2.system_id,
min(RQ2.rank) as min_rank
FROM (rank_query) RQ2
GROUP BY system_id) RS
因此對於同一示例,我們將獲得此結果
system_id. from_rank
1. 4
2. 9 -- this record will be removed by the filter_query
3. 12
最終查詢:
因此我們需要刪除過濾器查詢中存在的記錄,並且其排名大於from_rank。
DELETE FROM table_name WHERE
id in (
SELECT
RQ.id
FROM
rank_query RQ INNER JOIN filter_query FQ ON rq.system_id = FQ.system_id
INNER JOIN third_query RQD ON RQ.rank >= RQD.from_rank)
我希望這個主意能為任何語法錯誤對不起,我用手機接聽我喜歡這種查詢
您可以在查詢中使用LIMIT關鍵字指定偏移量,以便保留最新的5行。 但是,根據MySQL的文檔,沒有簡單的方法來限制從偏移量一直到最后一個偏移量。 相反,他們建議這樣做:
要檢索從某個偏移量到結果集結尾的所有行,可以為第二個參數使用較大的數字。
因此,此SQL應該可以解決問題:
從其中systemid = 1的ORDER BY值DESC LIMIT 5,45484848的表中刪除
嘗試執行以下操作以使最新的三個記錄的system_id等於1並且count大於5:
DELETE FROM <table_name> WHERE system_id = 1 AND value > 5 ORDER BY id DESC LIMIT 3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.