После вычисления текущей суммы с помощью оконной агрегатной функции sum()
просто выберите первую строку в соответствии с created_at
, которая превышает 1000:
SELECT *
FROM (
SELECT order_id, created_at
, sum(price) OVER (ORDER BY created_at) AS sum_price
FROM orders
) sub
WHERE sum_price >= 1000
ORDER BY created_at
LIMIT 1;
Это должно быть быстрее, чем версия @ Gordon, потому что выбор первого в том же порядке, который уже используется в оконной функции, намного дешевле, чем вычисление значения для каждой строки, которая не может быть саргируемой.
Я использую sum_price >= 1000
, так что достижение 1000 тоже подходит. Если допускается только превышение, используйте >
вместо >=
.
В руководстве по оконным функциям говорится:
В дополнение к этим функциям любая встроенная или определяемая пользователем агрегатная функция может использоваться как оконная функция.
Следует отметить, что этот запрос всегда возвращает ровно одну строку, в отличие от запроса @Gordon. В случае, когда несколько строк с одинаковыми created_at
пересекают барьер 1000, все они будут квалифицированы в ответе Гордона (или он потерпит неудачу, см. Ниже), в то время как в моем случае выбрано только one
. Это будет произвольно, пока вы не добавляете больше элементов в ORDER BY
в качестве разрешения конфликтов. Нравиться:
ORDER BY created_at, order_id
В этом запросе есть два экземпляра ORDER BY, и так уж получилось, что вы можете изменить один или оба, чтобы заставить его работать. Сделайте это для обоих, чтобы порядок сортировки был одинаковым, это должно быть быстрее всего.
На самом деле, версия Гордона не прошла бы полностью в этом тестовом примере:
CREATE TEMP TABLE orders(order_id int, price int, created_at date);
INSERT INTO orders VALUES
(1, 500, '2013-07-01')
,(2, 400, '2013-07-02')
,(3, 100, '2013-07-03')
,(4, 100, '2013-07-03')
,(5, 100, '2013-07-03');
Вы можете исправить это, сделав порядок сортировки в оконной функции уникальным, как показано выше.
Или вы можете изменить определение кадра для оконной функции на:
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
Прочтите руководство, написанное мелким шрифтом. а>
Но в любом случае медленнее.
-> SQLfiddle
person
Erwin Brandstetter
schedule
18.07.2013