是否可以在窗口函数分区中进行过滤

时间:2014-05-27 20:12:48

标签: sql tsql

这是我创建的一个表,用于解释我想要做的事情:

create table #test (
    PlaceID int, 
    ItemID int, 
    ItemCount int, 
    Amount dec(11,2)
)

我想得到3件事:

  1. sum by Place
  2. 按地点和项目总和
  3. 按地点和非项目总和
  4. 前两个很简单:

    sum(Amount) over (partition by PlaceID) as PlaceAmount
    sum(Amount) over (partition by PlaceID, ItemID) as PlaceItemAmount
    

    但是,如何获得当前项目中不是当前项目的所有项目的总和?

    以下是设置了数据和查询的SQL Fiddle

3 个答案:

答案 0 :(得分:1)

select t1.PlaceID, t1.ItemID, t1.ItemCount
     , t1.Amount as 'AmtMe'
     , SumPlace.sum as 'AmtPlace' 
     , SumPlace.sum - t1.Amount as 'AmtPlaceNoMe'
  from #test as t1
  join (select PlaceID, sum(Amount) as 'sum'
          from #test 
         group by PlaceID) as SumPlace 
    on t1.PlaceID = SumPlace.PlaceID 

答案 1 :(得分:1)

这是否符合您的期望?基本上,取整个(按地点分区)并减去当前(按地点,项目分区)以获得余数。但是,我会提到将它保存在子查询中,以便每个函数和分区集只运行一次窗口聚合。

同样可以使用该逻辑进行计数。

select
    PlaceID,
    ItemID,
    ItemCount,
    Amount,
    PlaceItemCount,
    PlaceAmount,
    ItemAndPlaceAmount,
    PlaceAmount-ItemAndPlaceAmount as RemainderAmount
from (
  select
      PlaceID,
      ItemID,
      ItemCount,
      Amount,
      sum(ItemCount) over (partition by PlaceID) as PlaceItemCount,
      sum(Amount) over (partition by PlaceID) as PlaceAmount,
      sum(Amount) over (partition by PlaceID, ItemID) as ItemAndPlaceAmount
  from tblTest
  ) z

答案 2 :(得分:1)

SELECT
    PlaceID,
    ItemID,
    ItemCount,
    Amount,
    sum(ItemCount) over (partition BY PlaceID) AS PlaceItemCount,
    sum(Amount) over (partition BY PlaceID) AS PlaceAmount
  , sum(Amount) over (partition BY PlaceID, ItemID) AS PlaceItemAmount
  , sum(Amount) over (partition BY PlaceID)
  - sum(Amount) over (partition BY PlaceID, ItemID) AS PlaceItemAmountMinusGroup
  , sum(Amount) over (partition BY PlaceID) - Amount PlaceItemAmountMinusThis
FROM tblTest

PlaceItemAmountMinusGroup是按地点计算的总金额,不包括ItemID的总金额 PlaceItemAmountMinusThis是没有行数的地方总金额。

SQLFiddle demo