1
store item datekey onhand salesunits 
-------------------------------------------- 
001  A  50  65  2 
001  A  51  8  4 
001  A  52  0  8 
-------------------------------------------- 

我需要做的事情:獲得大於零的最新數量減去商店和商品銷售的總單位數。所以在上面的例子中,它將是8-14 = -6。T-SQL - 使用相關子查詢中的聚合的所有行的聚合

我正在使用相關的子查詢來確定最新的datekey,然後加入回主查詢。但很明顯,這樣做我失去相關必要的其他行的數據求和salesunits:

這是我和它是錯的:

select s1.Store, s1.Item, s1.OnHand, sum(salesunit) 
from sales s1 
    join (select top 1 store,item, max(DateKey) as datekey 
     from sales 
     where isnull(onhand,0) > 0 
      and DateKey in (50,51,52) 
     group by store, item) s2 on s2.store=s1.store and s2.item=s1.item and s2.datekey=s1.datekey 
group by s1.Store, s1.Item, s1.OnHand 

感謝您的幫助!

回答

2
; 
WITH totals AS (
    SELECT 
    *, 
    totalsalesunits = SUM(salesunits) OVER (PARTITION BY store, item), 
    rnk = ROW_NUMBER() OVER (PARTITION BY store, item 
           ORDER BY SIGN(onhand) DESC, datekey DESC) 
    FROM sales 
) 
SELECT 
    store, 
    item, 
    onhand, 
    totalsalesunits 
FROM totals 
WHERE rnk = 1 
+1

我是+1爲標誌。很好的接觸 – 2012-02-22 12:25:34

2

我會做這樣的事情:

首先是一些測試數據:

DECLARE @tbl TABLE 
     (
      store VARCHAR(4), 
      item VARCHAR(2), 
      datekey INT, 
      onhand INT, 
      salesUnits INT 
     ) 

INSERT INTO @tbl 
VALUES 
    ('001','A',50,65,2), 
    ('001','A',51,8,4), 
    ('001','A',52,0,8) 

類似這樣的查詢:

;WITH cteTotalSales AS 
(
    SELECT 
     SUM(tbl.salesUnits) OVER(PARTITION BY 1) AS TotalSalesUnit, 
     tbl.store, 
     tbl.item, 
     ISNULL(tbl.onhand,0) AS onhand, 
     tbl.salesUnits, 
     tbl.datekey 
    FROM 
     @tbl AS tbl 
), cteLatest AS 
(
    SELECT 
     RANK() OVER 
      (
       PARTITION BY cteTotalSales.store,cteTotalSales.item 
       ORDER BY cteTotalSales.datekey DESC 
      ) AS iRank, 
     cteTotalSales.store, 
     cteTotalSales.item, 
     cteTotalSales.onhand, 
     cteTotalSales.salesUnits, 
     cteTotalSales.datekey 
    FROM 
     cteTotalSales 
    WHERE 
     (cteTotalSales.onhand-cteTotalSales.TotalSalesUnit)>0 
) 
SELECT 
    * 
FROM 
    cteLatest 
WHERE 
    iRank=1 
2
;with a as 
(
select rn = row_number() over (partition by store, item order by case when onhand = 0 then -1 else datekey end desc), 
Store, Item, OnHand, salesunit 
from sales 
) 
select store, item, sum(case when rn = 1 then onhand end)-sum(salesunit) OnHand, sum(salesunit) sumsalesunit from a 
group by store, item