如何获取每个摘要依赖于另一列的摘要行?

时间:2013-02-27 22:59:57

标签: sql oracle11g analytics summary

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         

期望的结果

  1. ID有LOCK和
  2. ID有KEYS和
  3. KEYS的Total_lot是> 6和
  4. LOCK的Total_lot是> 4
  5. 输出:

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

2 个答案:

答案 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