0

Oracle11g

如何获得每对行满足最小总和的汇总行?当我指定时where total_lot > N,我排除了我想要保留的行。

我想回答这个数据问题:哪些 id 的 KEYS 的总手数大于 6 而 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         

期望的结果

  1. ID有LOCK和
  2. ID 有 KEYS 和
  3. KEYS 的 Total_lot 大于 6 并且
  4. LOCK 的 Total_lot 大于 4

输出:

 ITEM_ID   CODE   TOTAL_LOT
 -----     -----  --------
 1         KEYS   8
 1         LOCK   5
4

2 回答 2

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
                    )
于 2013-02-28T00:20:00.707 回答
0

这是一个解决方案。

解释

使用 Gordon 的查询选择所有满足数量要求的 item_id。此查询返回 ID=3,因为总 KEYS > 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
于 2013-04-18T14:27:25.033 回答