首页 > 解决方案 > 删除除一个之外的所有记录,并且仅使用“类型”中的字段值

问题描述

我有一个在 php 中运行的 MySQL 脚本——它的作用是当用户登录时,它会删除所有旧令牌,除了最新的 3 个令牌。

    DELETE tokens FROM tokens
    LEFT JOIN (    
    SELECT id
    FROM tokens
    WHERE users_id = :user_id
    ORDER BY access_time DESC
    LIMIT 3) AS newest
    ON tokens.id = newest.id
    WHERE tokens.users_id = :user_id AND newest.id IS NULL

这非常有效,但是我尝试对其进行修改,使其仅适用于类型设置为“API”或“APP”的所有令牌

所以理论上,1 个用户可以在同一张表中拥有 3 个 API 令牌和 3 个 APP 令牌。

我试着改变这条线

    WHERE tokens.users_id = :user_id AND newest.id IS NULL

    WHERE tokens.users_id = :user_id AND newest.id IS NULL AND tokens.type = "API"

但是它似乎不起作用,事实上它根本没有返回任何结果......我做错了什么?

我的表中的字段如下:

令牌:id users_id token create_time type access_time

用户: id 电子邮件密码 活动验证 create_time

标签: mysqlsql

解决方案


你的想法只是有点错误。

您正在修改的WHERE子句在DELETE语句中,但您想更改保留的内容,而不是删除的内容。您要保留的行在FROM子句的子查询中定义。所以这就是你想要放置新条件的地方。可能有一种更优雅的方法可以做到这一点,但是每个 3 个type,我只使用了一个UNION.

DELETE tokens
FROM tokens
LEFT JOIN 
(
  (SELECT id
   FROM tokens
   WHERE users_id =users_id AND tokens.type = "API"
   ORDER BY access_time DESC 
   LIMIT 3)
  UNION ALL
  (SELECT id
   FROM tokens
   WHERE users_id =users_id AND tokens.type = "APP"
   ORDER BY access_time DESC 
   LIMIT 3)
) AS newest 
    ON tokens.id = newest.id
WHERE 
  newest.id IS NULL;

这是一个有效的Rextester Demo


推荐阅读