我想删除最近的插入到" n"行。
例如:
DELETE FROM users
WHERE user_id = %s AND group_id = %s
ORDER BY message_date DESC
我理解它是一个语法错误并在网上搜索我发现许多stackoverflow答案告诉使用像
这样的表单DELETE FROM users
WHERE id IN (SELECT id ....)
不幸的是,我在该表上没有主键,它们只是没有自动增量的插入。
我该怎么做?
也许我应该喜欢
WITH t AS
(
SELECT *
FROM users
WHERE user_id = %s AND group_id = %s
ORDER BY message_date DESC
)
DELETE FROM t
???
答案 0 :(得分:3)
如果您的表没有任何序列号(例如,如果存在现有的多列主键),您仍然可以使用IN
过滤要删除的行:
DELETE FROM table_name
WHERE (key1, key2) IN (
SELECT key1, key2 FROM table_name ORDER BY date DESC LIMIT 2
);
根据您的具体情况,您可以使用:
DELETE FROM users
WHERE (user_id, group_id) IN (
SELECT user_id, group_id FROM users
WHERE user_id = %s AND group_id = %s
ORDER BY message_date DESC
);
答案 1 :(得分:1)
您可以使用ID修改您找到的代码:
DELETE users u
WHERE u.user_id = %s AND u.group_id = %s AND
u.message_date IN (SELECT u2.message_date
FROM users u2
WHERE u2.user_id = u.user_id AND
u2.group_id = u.group_id
ORDER BY u2.message_date DESC
LIMIT <n>
);
我希望您从中了解到有用的主键可以在数据库中使用。
注意:如果数据库中存在联系,则可以删除多行。
编辑:
让我补充一点,我更倾向于将其作为:
DELETE users u
FROM (SELECT u2.*,
ROW_NUMBER() OVER (PARTITION BY user_id, group_id ORDER BY message_date DESC) as seqnum
FROM users u2
) u2
ON u2.user_id = u.user_id AND u2.group_id = u.group_id AND
u2.message_date = u.message_date
WHERE u.user_id = %s AND u.group_id = %s AND
seqnum <= <n>;
这可确保删除准确的行,即使是绑定。
答案 2 :(得分:1)
如果订购时没有候选键,您可以随时使用ctid :(保证唯一)
DELETE FROM one
WHERE EXISTS (
SELECT *
FROM one x
WHERE x.oneseq <= 3 -- whatever condition
AND x.ctid = one.ctid
ORDER BY x.ctid
LIMIT 3 -- number of rows you want todelete
);
这也适用于row_number() OVER (PARTITION BY...ORDER BY ctid) as rn
。 (这当然是荒谬的,因为ctid
订单或多或少随机