我需要一个查询。Delete
表中除前 N 行之外的所有行。该表只有一列。喜欢,
|friends_name|
==============
| Arunji |
| Roshit |
| Misbahu |
| etc... |
此列也可能包含重复的名称。
包含重复的名称
只有一列。
我需要一个查询。Delete
表中除前 N 行之外的所有行。该表只有一列。喜欢,
|friends_name|
==============
| Arunji |
| Roshit |
| Misbahu |
| etc... |
此列也可能包含重复的名称。
包含重复的名称
只有一列。
如果您可以通过 对记录进行排序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 子句中添加计数。
如果您没有 id 字段,我想您使用字母顺序。
DELETE FROM friends
WHERE friends_name
NOT IN (
SELECT * FROM (
SELECT friends_name
FROM friends
ORDER BY friends_name ASC
LIMIT 10) r
)
您删除除 10 个第一之外的所有行(字母顺序)
我只是想跟进这个相对较老的问题,因为现有答案没有满足要求和/或不正确。问题表明名称可以重复,但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
. 因此,按照要求在单个查询中执行此操作似乎是不可能的;我们必须手动执行这些步骤。
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供参考。
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 |