SQL Server:特定范围之间的数据

时间:2015-10-27 05:58:06

标签: sql sql-server range sql-server-2014

我有一个像这样的数据

stories  value
--------------------------
0        2194940472.78964
1        1651820586.1447
2        627935051.75
3        586994698.4272
4        89132137.57
5        134608008
6        40759564
7        0
8        0
10       0
11       0
12       0
13       26060602
17       0
18       0
19       84522335
20       316478066.045
24       0

我想按照范围总结

我期待的输出

stories            value
0-3                125201021
4-7                215453123
8-12               453121545
12-max(numstories) 21354322

我尝试了这个但却无法弄清楚出了什么问题

select t.NumStories, SUM(t.bldnvalue) 
from 
    (select 
         a.NumStories,
         case 
            when a.NumStories between 0 and 3 then sum(a.BldgValue)
            when a.NumStories between 4 and 7 then sum(a.BldgValue)
            when a.NumStories between 8 and 12 then sum(a.BldgValue)
            when a.NumStories between 13 and max(a.NumStories) then sum(a.BldgValue)
         end as bldnvalue 
     from 
         dbo.EDM_CocaCola_Coca_Cola_Company_1_1 a 
     group by 
         a.NumStories) t
group by 
    t.NumStories

使用此查询我得到此输出

NumStories  value
-------------------------------
0           2194940472.78964
3           586994698.4272
12          0
6           40759564
7           0
1           1651820586.1447
24          0
18          0
10          0
4           89132137.57
19          84522335
13          26060602
5           134608008
2           627935051.75
17          0
11          0
20          316478066.045
8           0 

4 个答案:

答案 0 :(得分:2)

我喜欢这个结果,我尝试使用BIN概念。我认为唯一的问题是你的最大垃圾箱。我不明白你是如何得到你的输出金额的。第一个记录值是'2,194,940,472.78964',它大于你在0-3 bin中的值

if OBJECT_ID('tempdb..#Test') is not null
    drop table #Test;

Create table #Test (
                        Stories int
                        , Value float
                    )
insert into #Test
values
 (0 , 2194940472.78964)
, (1 , 1651820586.1447 )
, (2 , 627935051.75    )
, (3 , 586994698.4272  )
, (4 , 89132137.57     )
, (5 , 134608008       )
, (6 , 40759564        )
, (7 , 0               )
, (8 , 0               )
, (10, 0               )
, (11, 0               )
, (12, 0               )
, (13, 26060602        )
, (17, 0               )
, (18, 0               )
, (19, 84522335        )
, (20, 316478066.045   )
, (24, 0               )



if OBJECT_ID('tempdb..#Bins') is not null
    drop table #Bins;
create Table #Bins(
                        Label varchar(20)
                        , Min int
                        , Max int
                    )

insert into #Bins values
 ('0-3', 0, 3)
, ('4-7', 4, 7)
, ('8-12', 8, 12)
, ('13 - Max', 13, 999999999)

Select b.Label
    , sum(t.Value) as Value
from #Test t 
join #Bins b
    on t.stories between b.Min and b.Max
Group by b.Label
order by 1

输出:

Label                Value
-------------------- ----------------------
0-3                  5061690809.11154
13 - Max             427061003.045
4-7                  264499709.57
8-12                 0

答案 1 :(得分:1)

你可以试试这个:

SELECT '0-3' AS stories,
       SUM(value) AS value
FROM dbo.EDM_CocaCola_Coca_Cola_Company_1_1
WHERE stories BETWEEN 0 AND 3

UNION ALL

SELECT '4-7' AS stories,
       SUM(value) AS value
FROM dbo.EDM_CocaCola_Coca_Cola_Company_1_1
WHERE stories BETWEEN 4 AND 7

UNION ALL

...

答案 2 :(得分:1)

Just build the grouping string first that you want and group by that variable.

select 
     case 
        when a.NumStories between 0 and 3 then '0-3'
        when a.NumStories between 4 and 7 then '4-7'
        when a.NumStories between 8 and 12 then '8-12'
        when a.NumStories >= 13 then '13-max'
     end as stories,
     sum(a.BldgValue) as value
 from 
     dbo.EDM_CocaCola_Coca_Cola_Company_1_1 a 
 group by 1;

If you really want to print the max too, then you can put in a subquery in the "13-max" line as (SELECT MAX(BldgValue) FROM dbo.EDM_CocaCola_Coca_Cola_Company_1_1)

答案 3 :(得分:1)

这是CTE的解决方案,它可以适用于任何数据集,而无需复制代码。

declare @YourTable table(stories int, value money)
declare @GroupMemberCount int=4

insert @YourTable (stories,value) values (0,5),(1,10),(2,11),(3,7),(4,18),(5,13),(7,15)

;with cte as
(
    select c.stories+v.i*@GroupMemberCount FirstGroupMember, c.stories+v.i*@GroupMemberCount+@GroupMemberCount -1 LastGroupMember
        ,CAST(c.stories+v.i*@GroupMemberCount as varchar(50))
            +'-'+CAST(c.stories+v.i*@GroupMemberCount+@GroupMemberCount -1 as varchar(50))GroupName
    from (select MIN(stories) stories from @YourTable) c
        cross join (values (0),(1),(2),(3),(4)/* and so on */) v(i)
    where exists (select * from @YourTable yt where yt.stories>=c.stories+v.i*3)
)
select c.GroupName, SUM(yt.value)
from cte c
     JOIN @YourTable yt ON yt.stories BETWEEN c.FirstGroupMember AND C.LastGroupMember
GROUP BY c.GroupName