我有一个包含数十万行的表,分配给用户。 e.g:
itemid | userid | etc
1 | 1 | etc
2 | 1 | etc
3 | 1 | etc
4 | 3 | etc
5 | 3 | etc
6 | 3 | etc
etc | etc | etc
用户可以分配给他或她的任意数量的项目。即从0到无穷大的任何数字。我的问题是我想要一个SQL查询,它将删除每个用户的所有项目,但保留20.如果用户少于20,例如,只分配了10个项目,则必须保留所有10个。
我该怎么做?
更新
如果用户有50个项目,ID为1 - 50,则必须返回项目30 - 50.换句话说,该用户最后插入20个项目。
答案 0 :(得分:2)
假设我们要删除除了每个用户最近的两个条目之外的所有条目......
CREATE TABLE my_table(itemid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,userid INT NOT NULL);
INSERT INTO my_table VALUES
(1, 1),
(2, 1),
(3, 1),
(4, 3),
(5, 3),
(6, 3);
SELECT * FROM my_table;
+--------+--------+
| itemid | userid |
+--------+--------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 3 |
| 5 | 3 |
| 6 | 3 |
+--------+--------+
这是一个选择要删除的行的查询...
SELECT a.*
FROM my_table a
LEFT
JOIN
( SELECT x.*, COUNT(*) FROM my_table x JOIN my_table y ON y.userid = x.userid AND y.itemid >= x.itemid GROUP BY x.itemid HAVING COUNT(*) <=2)b
ON b.itemid = a.itemid
WHERE b.itemid IS NULL;
+--------+--------+
| itemid | userid |
+--------+--------+
| 1 | 1 |
| 4 | 3 |
+--------+--------+
...这是一个删除它们的查询...
DELETE a
FROM my_table a
LEFT
JOIN
( SELECT x.*, COUNT(*) FROM my_table x JOIN my_table y ON y.userid = x.userid AND y.itemid >= x.itemid GROUP BY x.itemid HAVING COUNT(*) <=2)b
ON b.itemid = a.itemid
WHERE b.itemid IS NULL;
SELECT * FROM my_table;
+--------+--------+
| itemid | userid |
+--------+--------+
| 2 | 1 |
| 3 | 1 |
| 5 | 3 |
| 6 | 3 |
+--------+--------+
答案 1 :(得分:0)
试试这个
delete from Fruits where itemid
not in (select itemid from (select itemid from Fruits where userid = 1
ORDER BY itemid desc limit 20)x )
and userid=1
答案 2 :(得分:0)
该代码的工作原理如下:
SELECT:
SET @count=1;
SET @last_user_id=0;
SELECT * FROM (
SELECT *,
case
when (@last_user_id = userid)
then
@count:=@count+1
else @count:=1 end as count,
case
when (@last_user_id!=userid)
then
@last_user_id:=userid
end
as new
FROM <tablename> ORDER BY userid, itemid DESC) AS inner_table WHERE count > 20
删除:
SET @count=1;
SET @last_user_id=0;
DELETE FROM (
SELECT *,
CASE
WHEN (@last_user_id = userid)
THEN
@count:=@count+1
ELSE
@count:=1
END
AS count,
CASE
WHEN (@last_user_id!=userid)
THEN
@last_user_id:=userid
END
AS new
FROM <tablename> ORDER BY userid, itemid DESC) AS inner_table WHERE count > 20
答案 3 :(得分:-1)
这对我有用:
DELETE FROM table WHERE itemid NOT IN (
SELECT itemid
FROM (
SELECT *
FROM table
WHERE userid = 1
ORDER BY itemid DESC
LIMIT 20
) x
)
AND userid = 1