Нахождение максимума и минимума с помощью оператора Group By и оператора Join - PullRequest
0 голосов
/ 22 марта 2019

В моей базе 3 таблицы. Order, Item и Order_has_item созданы многими ко многим отношениям между заказами и товарами.

enter image description here

Что мне нужно сделать, это получить order_ids заказов в течение определенного периода времени, а затем получить items, связанных с этим набором заказов, от order_has_item. Затем я должен получить количество qty (количество) предметов, сгруппировав их с помощью item_id, а затем найти проданные предметы максимальное и минимальное количество раз.

Это то, что я имею до сих пор:

SELECT a.item_id,sum(a.qty) 
FROM order_has_item a 
FULL OUTER JOIN order b ON a.order_id = b.order_id 
WHERE TO_CHAR(b.datetime, 'MON') = 'JAN'
GROUP BY a.item_id 
ORDER BY sum(a.quantity);

Чего мне не хватает? Я попытался использовать предложение having, но оно не сработает.

-UPDATE-

enter image description here

Пример вывода. Мне нужно взять максимальный и минимальный результаты из общего количества. Таким образом, максимум должен быть Item Id 1 и 45, а минимум должен быть Item ID 62

Ответы [ 3 ]

0 голосов
/ 22 марта 2019

Я никогда не использовал полное внешнее соединение. Это может работать

SELECT * FROM (SELECT *, MAX(CountItems) AS maxItems, MIN(CountItems) AS minItems FROM ( SELECT ohi.item_id, sum(ohi.qty) AS [CountItems] FROM order o JOIN order_has_item ohi ON o.order_id=ohi.order_id where TO_CHAR(b.datetime, 'MON') = 'JAN' group by ohi.item_id) JanItems ) JanItemsWMaxAndMin WHERE CountItems = minItems or CountItems = maxItems

`

0 голосов
/ 22 марта 2019

попробовать:

with t as (
  SELECT i.item_id, sum(ohi.qty) as qty_sum 
    FROM order_has_item ohi 
   INNER JOIN orders o 
      ON o.order_id = ohi.order_order_id
   INNER JOIN item i 
      ON i.item_id = ohi.item_item_id
   WHERE o.datetime BETWEEN to_DATE('2018-12-15', 'yyyy-mm-dd') 
                        AND ADD_MONTHS(to_DATE('2018-12-15', 'yyyy-mm-dd') , 1)
   GROUP BY i.item_id
)
SELECT min(t.qty_sum) as min_sum,  
       max(t.qty_sum) as max_sum,
       min(t.item_id) KEEP (DENSE_RANK FIRST ORDER BY t.qty_sum) as item_min,
       min(t.item_id) KEEP (DENSE_RANK LAST ORDER BY t.qty_sum) as item_max
  FROM t;

как вы можете видеть на демонстрации, результат будет таким же, как и у ответа до *. 1004 * demo

0 голосов
/ 22 марта 2019

Логика вашего запроса кажется неправильной: почему 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() для отображения всех из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...