Запрос Oracle sql для ГРУППИРОВКИ, УПОРЯДОЧЕНИЯ и удаления самых старых записей по идентификатору

#sql #oracle #group-by #sql-order-by

Вопрос:

Я хочу написать запрос oracle sql, чтобы сохранить первые три последние записи, упорядоченные по метке ВРЕМЕНИ, и удалить остальные для каждого идентификатора машины. Я хочу знать, насколько эффективно я могу это сделать. Надеюсь, вы поняли мой вопрос!!

Ниже приведена таблица для примера. Все записи с USERFILE = 0 могут быть отфильтрованы в sql-запросе.

введите описание изображения здесь

**Результат после — группировка по идентификатору машины и сортировка по МЕТКЕ времени **

введите описание изображения здесь

После того, как вы оставите первые 3 последние записи на MACHINE_ID и удалите самые старые записи, конечный результат должен быть

введите описание изображения здесь

Комментарии:

1. Пожалуйста, опубликуйте примеры данных и желаемые выходные данные в текстовом формате. Также покажите свою текущую попытку и опишите, в чем с ней проблема.

Ответ №1:

Одним из методов является:

 delete from t
    where t.timestamp not in (select t2.timestamp
                              from t t2
                              where t2.machine_id = t.machine_id 
                              order by t2.timestamp desc
                              fetch first 3 rows only
                             );
 

Для повышения производительности вам нужен индекс (machine_id, timestamp desc) .

Комментарии:

1. Это сработало, но какова будет производительность, если мы попробуем это в больших наборах данных?

2. @JMBA . . . С указанным индексом (который я только что добавил) производительность должна быть в порядке-сопоставима с другими методами.

3. Спасибо за ваш ответ. Это мой последний запрос, который я собираюсь использовать. Идентификатор из запроса является первичным ключом, поэтому я думаю, что с точки зрения производительности это будет нормально. M1.ID из матриц файлов M1, где M1.ID НЕ ВХОДИТ (выберите M2.ID из файлов матрицы M2, где M2.machine_id = M1.machine_id и файл пользователя = 1 порядок по метке времени M2.сначала извлеките :только строки maxFiles)

Ответ №2:

Вы можете пронумеровать строки для каждой машины, а затем удалить все строки с числом больше 3. В идеале мы могли бы просто удалить из запроса, но я получаю ORA-01732: операция манипулирования данными не разрешена в этом представлении при попытке сделать это в Oracle 19c.

Нам нужно сделать два шага отсюда:

  1. найдите строки
  2. удалите строки

Оператор, использующий rowid для быстрого доступа к строкам:

 delete from mytable
where rowid in
(
  select rowid
  from 
  (
    select
      rowid,
      row_number() over (partition by machine_id order by timestamp desc) as rn
    from mytable
  )
  where rn > 3
);