我需要一个查询。 Delete
表中除前N行之外的所有行。该表只有一列。像,
|friends_name|
==============
| Arunji |
| Roshit |
| Misbahu |
| etc... |
此列也可能包含重复的名称。
包含重复的名称
只有一栏。
答案 0 :(得分:10)
如果您可以按friends_name
订购记录,如果没有重复记录,您可以使用此记录:
DELETE FROM names
WHERE
friends_name NOT IN (
SELECT * FROM (
SELECT friends_name
FROM names
ORDER BY friends_name
LIMIT 10) s
)
请参阅小提琴here。
或者你可以使用它:
DELETE FROM names ORDER BY friends_name DESC
LIMIT total_records-10
其中total_records为(SELECT COUNT(*) FROM names)
,但您必须通过代码执行此操作,不能将计数放入查询的LIMIT子句中。
答案 1 :(得分:3)
如果您没有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个第一行(字母顺序)的行
答案 2 :(得分:1)
我只想跟进这个相对较旧的问题,因为现有的答案不能满足要求和/或不正确。该问题指出名称可以重复,但是只有前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。
在没有唯一索引和其他字段来确定“前N个”含义的情况下,我们按照数据库返回的顺序进行操作。我们可能很想做这样的事情(用高数字代替99999):
DELETE FROM names LIMIT 99999 OFFSET 3
但是根据MySQL docs,尽管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 |