8

我需要一个查询。Delete表中除前 N 行之外的所有行。该表只有一列。喜欢,

|friends_name|
==============
| Arunji     |
| Roshit     |
| Misbahu    |
| etc...     |

此列也可能包含重复的名称。

  • 包含重复的名称

  • 只有一列。

4

3 回答 3

14

如果您可以通过 对记录进行排序friends_name,并且没有重复记录,则可以使用以下命令:

DELETE FROM names
WHERE
  friends_name NOT IN (
    SELECT * FROM (
      SELECT friends_name
      FROM names
      ORDER BY friends_name
      LIMIT 10) s
  )

在此处查看小提琴。

或者你可以使用这个:

DELETE FROM names ORDER BY friends_name DESC
LIMIT total_records-10

其中 total_records 是(SELECT COUNT(*) FROM names),但您必须通过代码执行此操作,您不能在查询的 LIMIT 子句中添加计数。

于 2013-06-25T08:30:00.737 回答
3

如果您没有 id 字段,我想您使用字母顺序。

MYSQL

DELETE FROM friends 
WHERE friends_name 
NOT IN (
    SELECT * FROM (
        SELECT friends_name 
        FROM friends 
        ORDER BY friends_name ASC
        LIMIT 10) r
)

您删除除 10 个第一之外的所有行(字母顺序)

于 2013-06-25T08:29:19.613 回答
3

我只是想跟进这个相对较老的问题,因为现有答案没有满足要求和/或不正确。问题表明名称可以重复,但N必须保留顶部。其他答案将删除不正确的行和/或不正确的行数。

例如,如果我们有这张表:

|friends_name|
==============
| Arunji     |
| Roshit     |
| Misbahu    |
| Misbahu    |
| Roshit     |
| Misbahu    |
| Rohan      |

我们想删除除前 3 行之外的所有行 ( N = 3),预期结果将是:

|friends_name|
==============
| Arunji     |
| Roshit     |
| Misbahu    |

当前所选答案的DELETE陈述将导致:

|friends_name|
==============
| Arunji     |
| Misbahu    |
| Misbahu    |
| Misbahu    |

看到这个sqlfiddle。这样做的原因是它首先按字母顺序对名称进行排序,然后取前 3 个名称,然后删除所有不等于该名称的名称。但是由于它们是按名称排序的,它们可能不是我们想要的前 3 个,并且不能保证我们最终只会得到 3 个。

在没有唯一索引和其他字段来确定“top N”是什么意思的情况下,我们按照数据库返回的顺序进行。我们可能想做这样的事情(用高数字替换 99999):

DELETE FROM names LIMIT 99999 OFFSET 3

但是根据MySQL 文档,虽然DELETE支持该LIMIT子句,但它不支持OFFSET. 因此,按照要求在单个查询中执行此操作似乎是不可能的;我们必须手动执行这些步骤。

解决方案 1 - 存放前 3 名的临时表

CREATE TEMPORARY TABLE temp_names LIKE names;
INSERT INTO temp_names SELECT * FROM names LIMIT 3;
DELETE FROM names;
INSERT INTO names SELECT * FROM temp_names;

这是sqlfiddle供参考。

解决方案 2 - 重命名的新表

CREATE TABLE new_names LIKE names;
INSERT INTO new_names SELECT * FROM names LIMIT 3;
RENAME TABLE names TO old_names, new_names TO names;
DROP TABLE old_names;

这是这个的sqlfiddle

无论哪种情况,我们都会在原始表中得到前 3 行:

|friends_name|
==============
| Arunji     |
| Roshit     |
| Misbahu    |
于 2018-11-10T18:00:19.890 回答