У меня есть таблица SQL foo в Oracle с отметкой времени bar. Я хочу обновить метки времени, чтобы они соответствовали максимальной метке времени в диапазоне 8–16 секунд. (Временные метки в любом случае приходят «группами»; они либо меньше 8 секунд, либо больше 16 секунд.) Да, и я провожу тесты с H2. Я пробовал это:
UPDATE foo update_foo SET bar =
(SELECT MAX(bar) FROM foo
WHERE bar > update_foo.bar - interval '8' second
AND bar < update_foo.bar + interval '8' second)
H2 это не понравилось. Верен ли мой синтаксис для Oracle, если я хочу сделать это стандартным способом? Проблема в H2 или в моем синтаксисе? Или есть способ лучше?


Это Н2. Ваш оператор соответствует Oracle 12c и тому времени, когда были введены временные метки (10g?).
Лучший способ зависит от H2, чего я не знаю.
Обновлено: вы можете посмотреть здесь для получения дополнительной информации.
Подход грубой силы, который должен быть довольно медленным, заключался бы в открытии курсора для
select key, max(bar) from foo group by key
и в цикле выберите строку и выполните следующее:
update foo set bar = max_fetched_bar where key = fetched_key
Ужасный. Совершенно ужасно. Но, возможно, обновление и выбор достаточно просты для анализа в H2.
Если H2 поддерживает выполнение анонимных блоков PL / SQL, тогда вы можете выполнить исходное обновление в блоке PL / SQL и, надеюсь, избежать H2.
Я люблю H2, но он обязательно отличается от Oracle. Это тот случай, когда этот крошечный механизм базы данных использует альтернативный синтаксис для той же цели. Но предупреждаю, что это не подражатель Oracle.
Предполагая, что ваши данные:
create table foo (
bar timestamp
);
insert into foo (bar) values ('2018-01-01 12:34:56');
insert into foo (bar) values ('2018-01-01 12:34:52');
insert into foo (bar) values ('2018-01-01 12:34:57');
insert into foo (bar) values ('2018-01-02 12:34:10');
insert into foo (bar) values ('2018-01-02 12:34:11');
Запрос:
update foo update_foo set bar =
(select max(bar) from foo
where bar > dateadd('second', -8, update_foo.bar)
and bar < dateadd('second', 8, update_foo.bar)
);
Результат:
BAR
---------------------
2018-01-01 12:34:57.0
2018-01-01 12:34:57.0
2018-01-01 12:34:57.0
2018-01-02 12:34:11.0
2018-01-02 12:34:11.0