我对数据库和Postgres还是陌生的。 我有一个名为名称的表,该表具有2列名称和值,每x秒用新的名称值对更新。我的要求是在任何时间点仅保留3个正值和3个负值,并在每次表更新期间删除其余行。 我使用以下查询删除旧行,并保留按值排序的3个正值和3个负值。
delete from names
using (select *,
row_number() over (partition by value > 0, value < 0 order by value desc) as rn
from names ) w
where w.rn >=3
我对在分区语句中使用条件式值> 0表示怀疑。这种方法正确吗?
例如
像这样删除之前的表:
name | value
--------------
test | 10
test1 | 11
test1 | 12
test1 | 13
test4 | -1
test4 | -2
删除后我的表应如下所示:
name | value
--------------
test1 | 13
test1 | 12
test1 | 11
test4 | -1
test4 | -2
答案 0 :(得分:1)
这通常可以按预期工作:value > 0
将值聚集到所有大于0的数字和所有<= 0的数字中。ORDER BY value
将这两个组按预期排序。
所以,唯一的改变是:
row_number() over (partition by value >= 0 order by value desc)
, value < 0
(因为:为什么要将正值分为负数和其他?正数组中没有负数,反之亦然。)value > 0
更改为value >= 0
,以便尽可能长地忽略0
删除:如果要保留每个方向的前3个值:
w.rn >= 3
更改为w.rn > 3
(它也保留了第3个元素)where n.value = w.value AND w.rn > 3
所以,最后:
delete from names n
using (select *,
row_number() over (partition by value >= 0 order by value desc) as rn
from names ) w
where n.value = w.value AND w.rn > 3
答案 1 :(得分:0)
如果不是很难删除其他行,则可以只选择您感兴趣的行:
WITH largest AS (
SELECT name, value
FROM names
ORDER BY value DESC
LIMIT 3),
smallest AS (
SELECT name, value
FROM names
ORDER BY value ASC
LIMIT 3)
SELECT * FROM largest
UNION
SELECT * FROM smallest
ORDER BY value DESC