使用Group By和Join语句查找最大值和最小值

时间:2019-03-22 00:12:21

标签: sql oracle

我的数据库中有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

样本输出。我需要从“总数”中获取最大和最小结果。因此,最大值应为项目ID 1和45,而最小值应为项目ID 62

3 个答案:

答案 0 :(得分:0)

您的查询逻辑似乎不正确:为什么要自FULL OUTER JOINorder

这是一个简单的聚合查询,其中JOIN s orderorder_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()来显示所有记录。

答案 1 :(得分:0)

我从未使用过完全外部联接。这可能有效

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

`

答案 2 :(得分:0)

尝试:

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;

在演示中可以看到,它的结果与之前做的回答相同。demo