我有一个哈希表:
CREATE TABLE hash_table ( hash_id bigserial,
user_name varchar(80),
hash varchar(80),
exp_time bigint,
PRIMARY KEY (hash_id));
INSERT INTO hash_table (hash_id, user_name, exp_time) VALUES
(1, 'one', 10),
(2, 'two', 20),
(3, 'three', 31),
(4, 'three', 32),
(5, 'three', 33),
(6, 'three', 33),
(7, 'three', 35),
(8, 'three', 36),
(9, 'two', 40),
(10, 'two', 50),
(11, 'one', 60),
(12, 'three', 70);
exp_time - 哈希的到期时间。行创建时exp_time = now() + delta_time
我需要一个结果:
(1, 'one', 10),
(2, 'two', 20),
(7, 'three', 35),
(8, 'three', 36),
(9, 'two', 40),
(10, 'two', 50),
(11, 'one', 60),
(12, 'three', 70);
它包含许多user_name-hash对。 user_name可能会占用很多时间。
如何删除所有行但是(几个,例如10个)最新指定的user_name?
我发现了this解决方案(对于mySQL但我希望它有效)但它会删除所有其他user_names
DELETE FROM `hash_table`
WHERE user_name NOT IN (
SELECT user_name
FROM (
SELECT user_name
FROM `hash_table`
ORDER BY exp_time DESC
LIMIT 10 -- keep this many records
)
);
答案 0 :(得分:1)
这将为每个user_name保留3条最新记录:
DELETE FROM hash_table h
USING
(
SELECT
user_name,
exp_time,
row_number() OVER (PARTITION BY user_name ORDER BY exp_time DESC) AS r
FROM
hash_table
) AS s
WHERE
h.user_name = s.user_name
AND h.exp_time<s.exp_time
AND s.r=3
答案 1 :(得分:0)
您可以使用row_number
按降序排列基于exp_time
的用户行。然后从表中删除包含10个以上条目的用户行。
delete from hash_table as h
using
(
SELECT user_name, exp_time,
row_number() over(partition by user_name order by exp_time desc) as rn
FROM hash_table
) as t
where h.user_name = t.user_name and h.exp_time <= t.exp_time and t.rn > 10;
答案 2 :(得分:0)
DELETE FROM hash_table WHERE hash_id NOT IN (SELECT hash_id FROM hash_table WHERE user_name = 'three' ORDER BY exp_time DESC LIMIT 3) AND user_name = 'three';
我自己回答:查询仅计算所需user_name
的行,而不是所有user_name
的行。