我的数据库中有3个表。 Order,Item和Order_has_item由订单和项目之间的多对多关系创建。
我需要做的是在特定时间段内获取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-
样本输出。我需要从“总数”中获取最大和最小结果。因此,最大值应为项目ID 1和45,而最小值应为项目ID 62
答案 0 :(得分:0)
您的查询逻辑似乎不正确:为什么要自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()
来显示所有记录。
答案 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