2017-02-09 24 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

相关问题