在table中只保留3个最高的正面和负面记录
Retain only 3 highest positive and negative records in a table
我是数据库和 postgres 的新手。
我有一个名为 names 的 table,它有 2 列 name 和 value,每 x 秒更新一次新的名称值对。我的要求是在任何时间点只保留 3 个正值和 3 个负值,并在每次 table 更新期间删除其余行。
我使用以下查询删除旧行并保留按值排序的 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
我对在分区语句中使用 value > 0 这样的条件表示怀疑。这种方法正确吗?
例如,
A table 在删除之前像这样:
name | value
--------------
test | 10
test1 | 11
test1 | 12
test1 | 13
test4 | -1
test4 | -2
删除后我的 table 应如下所示:
name | value
--------------
test1 | 13
test1 | 12
test1 | 11
test4 | -1
test4 | -2
这通常按预期工作: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 个元素)
- 您需要将子查询与 table 条记录连接起来。在实际情况下,您应该为此使用 id 列。在您的示例中,您可以采用值列:
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
如果删除其他行不是硬性要求,您可以 select 只删除您感兴趣的行:
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
我是数据库和 postgres 的新手。 我有一个名为 names 的 table,它有 2 列 name 和 value,每 x 秒更新一次新的名称值对。我的要求是在任何时间点只保留 3 个正值和 3 个负值,并在每次 table 更新期间删除其余行。 我使用以下查询删除旧行并保留按值排序的 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
我对在分区语句中使用 value > 0 这样的条件表示怀疑。这种方法正确吗?
例如,
A table 在删除之前像这样:
name | value
--------------
test | 10
test1 | 11
test1 | 12
test1 | 13
test4 | -1
test4 | -2
删除后我的 table 应如下所示:
name | value
--------------
test1 | 13
test1 | 12
test1 | 11
test4 | -1
test4 | -2
这通常按预期工作: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 个元素) - 您需要将子查询与 table 条记录连接起来。在实际情况下,您应该为此使用 id 列。在您的示例中,您可以采用值列:
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
如果删除其他行不是硬性要求,您可以 select 只删除您感兴趣的行:
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