我有以下表格:
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条记录。
我如何在查询中执行此操作?
答案 0 :(得分:2)
如果你不总是有8条记录,并且想要从systemid = 1的表中选择最后3条记录,但是有很多记录,那么一个好方法是在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);
我希望这会有所帮助。
答案 1 :(得分:1)
这将是一个非常长的查询。您需要的是每个拥有5条以上记录的system_id,您要删除小于3级的记录。
我将分开查询并在最后使用名称。
1_ ranking_query:abriviation是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 abriviation:RQD
一个查询,知道我们应该从哪个等级开始删除对于mysql中的每个system_id我们需要再次重写第一个查询但是在这里我将使用Abriviation来保持答案简短。
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)
我希望这个想法对我使用手机回答的任何语法错误感到抱歉
答案 2 :(得分:0)
您可以在查询中使用LIMIT关键字指定偏移量,以保留最新的5行。然而,根据MySQL的文档,没有简单的方法可以将偏移限制为最后一个;相反,他们建议:
要检索从某个偏移量到结果集末尾的所有行,您可以使用一些大数字作为第二个参数。
所以这个SQL应该可以解决这个问题:
DELETE FROM table where systemid = 1 ORDER BY value DESC LIMIT 5,45484848
答案 3 :(得分:0)
尝试此操作以保留最新的三条记录,其中system_id等于1且count大于5:
document.getElementById ("endDate").addEventListener ("change", populateRentPaymentDates, false);
function populateRentPaymentDates(){
var endDate = document.getElementById("endDate").value;
if (endDate == ""){
return;
}
// Calculate your start date here
var startDate = endDate;
updateStartDate(startDate);
displayStartDate();
}
function updateStartDate(startDate){
document.getElementById("startDate").value = startDate;
}
function displayStartDate(){
document.getElementById("startDate").removeAttribute("hidden");
}