2016-05-12 51 views
1

我需要計算交易中產品的組合與其他產品不同,我正在努力如何在SQL 2008的單個select語句內完成此操作。然後這將成爲一個數據集來操縱在Reporting Services產品組合作爲單一計數

原始數據看起來像這樣

txn, prod, units 
1, a, 2 
1, c, 1 
2, a, 1 
2, b, 1 
2, c, 1 
3, a, 2 
3, b, 1 
4, a, 3 
4, c, 2 

那麼A + b =應,如果一個在同一跨數,但a或b應該等於一個如果沒有配對。所以a = 1和b = 1,但a + b = 1,a + b + a = 2,a + b + a + b = 2給出示例數據,這裏是我期望的結果,並解釋了爲什麼

txn 1 is 3 units -- 2a + c 
txn 2 is 2 units -- (a+b) + c 
txn 3 is 2 units -- (a+b) + a 
txn 4 is 5 units -- 3a + 2c 

我的查詢比這更復雜,包括其他的聚集,所以我想通過業務羣這因爲我需要在一個較低的穀物操縱

更新進度,我不能做的:

可能的解決方法,我已經根據我測量的產品生成了列。這使我可以在Txn上進行分組,因爲我現在正在聚合該字段。不確定是否有更好的方法來做到這一點,因爲它確實需要一點時間

CASE WHEN SUM(CASE WHEN Prod='a' then 1 else 0 end)- 
       SUM(CASE WHEN Prod='b' then 1 else 0 end)=0 
     THEN SUM(CASE WHEN Prod='a' then 1 else 0 end) 
     ELSE 0 END AS MixProd 
, CASE WHEN SUM(CASE WHEN Prod='a' then 1 else 0 end)- 
       SUM(CASE WHEN Prod='b' then 1 else 0 end)!=0 
     THEN ABS(SUM(CASE WHEN Prod='a' then 1 else 0 end)- 
        SUM(CASE WHEN Prod='b' then 1 else 0 end)) 
     ELSE 0 END AS NotMixProd 

我會那麼需要理清當前單位合計刪除臨時演員,但是這無疑給了我一開始

更新進度2:

在a或b爲0的情況下,它無法正確處理0,它仍然會爲混合提供值,因爲ab不爲零。我恢復到以前的草案,我失去了和按以下

, CASE   WHEN  SUM(CASE WHEN Prod='a' then 1 else 0 end) = 0 THEN 0 
       WHEN  SUM(CASE WHEN Prod='b' then 1 else 0 end) = 0 THEN 0 
       WHEN  SUM(CASE WHEN Prod='a' then 1 else 0 end)- 
          SUM(CASE WHEN Prod='b' then 1 else 0 end)=0 
       THEN  SUM(CASE WHEN Prod='a' then 1 else 0 end) 
       ELSE  ABS(SUM(CASE WHEN Prod='a' then 1 else 0 end)- 
          SUM(CASE WHEN Prod='b' then 1 else 0 end))  
       END AS MixProd 
     , CASE WHEN  SUM(CASE WHEN Prod='a' then 1 else 0 end)- 
          SUM(CASE WHEN Prod='b' then 1 else 0 end)!=0 
       THEN  ABS(SUM(CASE WHEN Prod='a' then 1 else 0 end)- 
          SUM(CASE WHEN Prod='b' then 1 else 0 end)) 
       ELSE 0  END AS NotMixProd 
+0

不明確。你能詳細說明嗎? –

+0

我希望GROUP BY txn,但我需要根據其他產品在同一個txn中的不同來計算產品。我不能簡單地把CASE當prod IN('a','b')然後0.5 else 1 end,因爲它們只在一起時值0.5,然後只有兩個在一起 – cockbeard

+0

想法是得到total = SUM ),sa = SUM(CASE prod WHEN'a'THEN units END,sb = ...',然後減去對的數量'res = total - CASE WHEN sa> sb THEN sb ELSE sa END' – Serg

回答

0

UPDATE擴展:這應該在SQL Server 2008中工作(基於LAG解決方案從here)。

以下是演示:http://rextester.com/GNI23706

WITH CTE AS 
(
    select txn, prod, units, 
    row_number() over (partition by txn order by prod) rn, 
    (row_number() over (partition by txn order by prod))/2 rndiv2, 
    (row_number() over (partition by txn order by prod)+1)/2 rnplus1div2, 
    count(*) over (partition by txn) partitioncount 
    from test_data 
) 

select 
txn, 
sum(case when prev_prod = 'a' and prod = 'b' and prev_units >= units then 0 
     when prev_prod = 'a' and prod = 'b' and prev_units < units then units - prev_units 
     else units 
    end) units 
from 
(
    select 
    txn, 
    prod, 
    units, 
    CASE WHEN rn%2=1 
     THEN MAX(CASE WHEN rn%2=0 THEN prod END) OVER (PARTITION BY txn,rndiv2) 
     ELSE MAX(CASE WHEN rn%2=1 THEN prod END) OVER (PARTITION BY txn,rnplus1div2) 
    END AS prev_prod, 
    CASE WHEN rn%2=1 
     THEN MAX(CASE WHEN rn%2=0 THEN units END) OVER (PARTITION BY txn,rndiv2) 
     ELSE MAX(CASE WHEN rn%2=1 THEN units END) OVER (PARTITION BY txn,rnplus1div2) 
    END AS prev_units 
    from cte 
) temp 
group by txn 

對於SQL Server 2012+,採用LAG:

select 
txn, 
sum(
case when prev_prod = 'a' and prod = 'b' and prev_units >= units then 0 
    when prev_prod = 'a' and prod = 'b' and prev_units < units then units - prev_units 
    else units 
end) units 
from 
(
    select 
    txn, 
    prod, 
    units, 
    lag(prod) over (partition by txn order by prod) prev_prod, 
    lag(units) over (partition by txn order by prod) prev_units 
    from test_data 
) temp 
group by txn 
0

我在一個臨時表是最好的方式去年底決定,因爲我無法整理歸類。所以,我終於調整了上面,因爲它是無法拿起備用物品正確

SUM(Units) AS OldUnits 
SUM(Units) - 
    (CASE WHEN 
SUM(CASE WHEN Prod='a' THEN 1 ELSE 0 END) = 0 THEN 0 WHEN 
SUM(CASE WHEN Prod='b' THEN 1 ELSE 0 END) = 0 THEN 0 WHEN 
SUM(CASE WHEN Prod='a' THEN 1 ELSE 0 END) - 
SUM(CASE WHEN Prod='b' THEN 1 ELSE 0 END) = 0 THEN 
SUM(CASE WHEN Prod='a' THEN 1 ELSE 0 END) WHEN 
(SUM(CASE WHEN Prod='a' THEN 1 ELSE 0 END) - 
SUM(CASE WHEN Prod='b' THEN 1 ELSE 0 END)) < 0 THEN 
SUM(CASE WHEN Prod='a' THEN 1 ELSE 0 END) ELSE 
SUM(CASE WHEN Prod='b' THEN 1 ELSE 0 END) END) AS NewUnits 

這是存儲在一個不是Temptable,我可以再上跨整理作爲下一步的代碼。爲我的目的工作正常,並幫助我克服了我對臨時工的溫和的非理性的恐懼