Логика вашего запроса кажется неправильной: почему self- FULL OUTER JOIN
таблица order
?
Вот простой агрегированный запрос, который JOIN
s order
и order_has_item
и возвращает общее количество для каждого элемента в течение заданного периода времени:
SELECT ohi.item_item_id, SUM(ohi.qty) total_qty
FROM order o
INNER JOIN order_has_item ohi ON ohi.order_order_id = o.oder_id
WHERE
o.datetime >= TO_DATE('2019-01-01', 'YYYY-MM-DD')
o.datetime < ADD_MONTHS(TO_DATE('2019-01-01', 'YYYY-MM-DD'), 1)
GROUP BY ohi.item_id
Я изменилусловие на таймфрейме, чтобы избежать использования TO_CHAR()
в левой части сравнения, потому что эта конструкция в основном побеждает существующий индекс по столбцу datetime
.
Теперь, если вы хотите выбрать элементыс наибольшим и наименьшим общим количеством за период, вы можете использовать ROW_NUMBER()
:
SELECT * FROM (
SELECT
x.*,
ROW_NUMBER() OVER(ORDER BY total_qty) rn_asc,
ROW_NUMBER() OVER(ORDER BY total_qty DESC) rn_desc
FROM (
SELECT ohi.item_item_id, SUM(ohi.qty) total_qty
FROM order o
INNER JOIN order_has_item ohi ON ohi.order_order_id = o.oder_id
WHERE
o.datetime >= TO_DATE('2019-01-01', 'YYYY-MM-DD')
o.datetime < ADD_MONTHS(TO_DATE('2019-01-01', 'YYYY-MM-DD'), 1)
GROUP BY ohi.item_id
) x
) y WHERE rn_asc = 1 OR rn_desc = 1
Если существуют даже самые верхние записи (т.е. более одного элемента имеют максимальное или минимальное количество), выможно использовать RANK()
вместо ROW_NUMBER()
для отображения всех из них.