#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.
Нам нужно сделать два шага отсюда:
- найдите строки
- удалите строки
Оператор, использующий 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
);