Сохраните только 3 самых положительных и отрицательных записей в таблице - PullRequest
0 голосов
/ 26 сентября 2019

Я новичок в базах данных и postgres как таковых.У меня есть таблица с именем names, в которой есть 2 столбца name и value, которые обновляются каждые 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

Ответы [ 2 ]

0 голосов
/ 26 сентября 2019

Если нет необходимости удалять другие строки, вместо этого вы можете выбрать только те, которые вас интересуют:

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
0 голосов
/ 26 сентября 2019

demo: db <> fiddle

Это работает в общем случае, как и ожидалось: value > 0 группирует значения по всем числам> 0 и всем числам <= 0. <code>ORDER BY valueэти две группы, как и следовало ожидать, хорошо.

Итак, единственное, что я хотел бы изменить:

row_number() over (partition by value >= 0 order by value desc) 
  1. удалить: , value < 0 (потому что: почему вы должны сгруппировать положительные значенияв отрицательное и другое? У вас нет отрицательных чисел в вашей положительной группе и наоборот.)
  2. измените: value > 0 на value >= 0, чтобы игнорировать 0 как можно дольше

Для удаления: если вы хотите сохранить 3 верхних значения для каждого направления:

  1. , вы должны изменить w.rn >= 3 на w.rn > 3 (он сохраняет 3-й элемента также)
  2. необходимо связать подзапрос с записями таблицы.В реальных случаях вы должны использовать столбцы 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
...