2017-02-09 63 views
0

我有一些獎勵數據。每個獎勵或授權都有一個授權號碼和金額以及該實體的ID。我通過ID總結了所有獎項的數量和所有獎項的數額。然後我根據範圍檢查返回一組總行或一個子集。如何找到爲什麼所有數據子集的和小於1總和

如何找出爲什麼所有子集的總和總是小於總集?這裏是我的存儲過程:

ALTER Procedure [dbo].[FLAS2_List_Awards_V3_PrepAwards] 
/* 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 0 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 1 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 2 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 3 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 4 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 5 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 6 
*/ 
-- populates #TempGrants according to range filter on TotalAmount 
(
    @Range int = 0 
        -- 0 = no filtering 
        -- 1 = < $1 million 
        -- 2 = < $5 million 
        -- 3 = < $10 million 
        -- 4 = < $15 million 
        -- 5 = < $20 million 
        -- 6 = > $20 million 
) 
As 
-- if calling sproc did not create this table, create here to allow unit testing 
IF OBJECT_ID('tempdb..#TempGrants') IS NULL 
BEGIN 
CREATE TABLE #TempGrants 
(
    ID   nchar(6) NOT NULL 
, TotalAwards decimal (16, 0) NULL 
, TotalAmount decimal (16, 0) NULL 
) 
END 
-- step 1. Summarize grants creating colums for HAVING filter 
CREATE TABLE #TempGrantsUnfiltered 
(
    ID   nchar(6) NOT NULL 
, TotalAwards decimal (16, 0) NULL 
, TotalAmount decimal (16, 0) NULL 
) 
insert into #TempGrantsUnfiltered 
(
    ID   
, TotalAwards 
, TotalAmount 
) 
select o.id 
     ,COUNT(o.GrantNumber) as TotalAwards 
     ,SUM(o.TotalObligatedAmount) as TotalAmount 
from dbo.FLAS2_Grants o 
group BY O.ID 
-- step 2. HAVING filter returns grant totals per range test 
insert into #TempGrants 
(
    ID   
, TotalAwards 
, TotalAmount 
) 
select o.id 
     ,TotalAwards 
     ,TotalAmount 
from #TempGrantsUnfiltered o 
WHERE 
    CASE 
     When @Range = 0 Then 1 
     When @Range = 1 AND TotalAmount < 1000000 Then 1 
     When @Range = 2 AND TotalAmount BETWEEN 1000001 AND 5000000 Then 1 
     When @Range = 3 AND TotalAmount BETWEEN 5000001 AND 10000000 Then 1 
     When @Range = 4 AND TotalAmount BETWEEN 10000001 AND 15000000 Then 1 
     When @Range = 5 AND TotalAmount BETWEEN 15000001 AND 20000000 Then 1 
     When @Range = 6 AND TotalAmount > 20000000 Then 1 
     ELSE 0  -- where 0 = 1 rejects record 
     END = 1  -- where 1 = 1 allows record 
order by TotalAmount desc  

當我執行以下塊:

EXECUTE FLAS2_List_Awards_V3_PrepAwards 0 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 1 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 2 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 3 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 4 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 5 
EXECUTE FLAS2_List_Awards_V3_PrepAwards 6 

我得到了使用SQL Management Studio中我的消息窗口下面的結果:

(597 row(s) affected) 

(597 row(s) affected) 

(597 row(s) affected) 

(65 row(s) affected) 

(597 row(s) affected) 

(341 row(s) affected) 

(597 row(s) affected) 

(89 row(s) affected) 

(597 row(s) affected) 

(39 row(s) affected) 

(597 row(s) affected) 

(23 row(s) affected) 

(597 row(s) affected) 

(39 row(s) affected) 

我不能說明子集中缺少的行或整個集合中的額外行。有任何想法嗎?

65 + 341 + 89 + 39 + 23 +39 = 596 < 597 
+0

不應該將'TotalAmount <1000000'設爲TotalAmount <= 1000000'或'TotalAmount <1000001'而不是? – SqlZim

+0

我同意SqlZim - 如果你有一個獎項,TotalAmount = 1000000,那麼這不會被任何過濾器拿起,但它會被未過濾的總數拾起。 – Skippy

回答

1

變化TotalAmount < 1000000TotalAmount < 1000001case表達。

+0

非常感謝!我懷疑有些愚蠢的錯誤,但只是看不到它。 –

+0

@JohnAdams樂於幫忙! – SqlZim

+0

只要小心 - 我一直都在看。人們並沒有明確指出他們想在範圍邊界發生什麼。您的存儲過程中的評論說,像@Range = 2過濾器TotalAmount <500萬美元,但您的case語句將過濾TotalAmount <= 500萬美元。你要哪個? – Skippy

相關問題