Oracle11g的
如何获取每对行满足最小总和的汇总行?
当我指定where total_lot > N
时,我会排除我想要保留的行。
我想回答这个数据问题:哪些ID具有总批量大于6的KEYS AND 具有LOCK,总批量大于4?
with inventory_items as
(
select 1 as item_id, 'KEYS' as code, '1020' as sub_code, 4 as lot_size from dual union all
select 1 as item_id, 'KEYS' as code, '2210' as sub_code, 4 as lot_size from dual union all
select 1 as item_id, 'LOCK' as code, '1610' as sub_code, 3 as lot_size from dual union all
select 1 as item_id, 'LOCK' as code, '1031' as sub_code, 2 as lot_size from dual union all
select 2 as item_id, 'KEYS' as code, '1020' as sub_code, 2 as lot_size from dual union all
select 2 as item_id, 'KEYS' as code, '2210' as sub_code, 1 as lot_size from dual union all
select 2 as item_id, 'LOCK' as code, '1610' as sub_code, 1 as lot_size from dual union all
select 2 as item_id, 'LOCK' as code, '1031' as sub_code, 3 as lot_size from dual union all
select 3 as item_id, 'KEYS' as code, '1031' as sub_code, 8 as lot_size from dual
)
select distinct item_id, code,
sum(lot_size) over (partition by item_id, code) as total_lot
from inventory_items
order by item_id, code
期望的结果
输出:
ITEM_ID CODE TOTAL_LOT
----- ----- --------
1 KEYS 8
1 LOCK 5
答案 0 :(得分:0)
你在找这样的东西吗?
select item_id, code, sum(lot_size)
from inventory_items ii
group by item_id, code
having sum(lot_size) > (case when code = 'KEYS' then 6
when code = 'LOCK' then 4
end)
顺便说一下,示例代码中的查询是执行group by
的一种非常麻烦的方式。
在回复您的评论时,假设您指的是两者的手数大小的总和:
select item_id, sum(lot_size)
from inventory_items ii
group by item_id
having sum(case when code = 'KEYS' then lot_size else 0 end) > 6 and
sum(case when code = 'LOCK' then lot_size else 0 end) > 4
如果您的意思是任何批量大于某个值,请在max()
子句中使用sum()
代替having
。
包含代码的最简单方法是将原始数据加入到此处。这是表达它的一种方式:
select *
from inventory_items ii
where ii.item_id in (select item_id, sum(lot_size)
from inventory_items ii
group by item_id
having sum(case when code = 'KEYS' then lot_size else 0 end) > 6 and
sum(case when code = 'LOCK' then lot_size else 0 end) > 4
)
答案 1 :(得分:0)
这是一个解决方案。
<强>解释强>
使用Gordon的查询选择符合数量要求的所有item_ids。此查询返回ID = 3,因为总KEYS&gt; 6.
select item_id,
code,
sum(lot_size) total_lot
from inventory_items
group by item_id, code
having sum(lot_size) > (case
when code = 'KEYS' then 6
when code = 'LOCK' then 4
end)
输出
ITEM_ID CODE TOTAL_LOT
------------------------
1 KEYS 8
1 LOCK 5
3 KEYS 8
现在,您需要排除ID = 3,因为您的要求是仅包含具有KEYS和LOCK的ID。也就是说,您希望每个item_id返回两行。因此,请执行上一个查询并添加一个计算item_id数量的列。
select item_id,
code,
total_lot,
count(*) over (partition by item_id) as item_count
from (
select item_id,
code,
sum(lot_size) total_lot
from inventory_items
group by item_id, code
having sum(lot_size) > (case
when code = 'KEYS' then 6
when code = 'LOCK' then 4
end)
)
<强>输出强>
ITEM_ID CODE TOTAL_LOT ITEM_COUNT
------- ---- ---------- ----------
1 KEYS 8 2
1 LOCK 5 2
3 KEYS 8 1
这为您提供了一个列,可以过滤行数,但要使用 你需要再次筑巢。
select item_id,
code,
total_lot
from (
select item_id,
code,
total_lot,
count(*) over (partition by item_id) as item_count
from (
select item_id,
code,
sum(lot_size) total_lot
from inventory_items
group by item_id, code
having sum(lot_size) > (case
when code = 'KEYS' then 6
when code = 'LOCK' then 4
end)
)
) where item_count=2
<强>输出强>
ITEM_ID CODE TOTAL_LOT
------------------------
1 KEYS 8
1 LOCK 5