Pivot / Aggregate分数范围内?

时间:2014-07-07 08:30:00

标签: sql-server-2008 pivot

我有一张大约12,000行的表,每一行都有一个“点数”。我想选择点在一个范围内的每个行数的计数,例如0 - 1000,1000 - 2000等

目前我正在使用“长途回合”方法,但有没有更简单的方法来实现这一目标?

select
  SUM(pts.[UNDER 1000]) AS 'UNDER 1000'
, SUM(pts.[UPTO 2000]) AS 'UPTO 2000'
, SUM(pts.[UPTO 3000]) AS 'UPTO 3000'
, SUM(pts.[UPTO 4000]) AS 'UPTO 4000'
, SUM(pts.[UPTO 5000]) AS 'UPTO 5000'
, SUM(pts.[UPTO 6000]) AS 'UPTO 6000'
, SUM(pts.[UPTO 7000]) AS 'UPTO 7000'
, SUM(pts.[UPTO 8000]) AS 'UPTO 8000'
, SUM(pts.[UPTO 9000]) AS 'UPTO 9000'
, SUM(pts.[UPTO 10000]) AS 'UPTO 10000'
from 
(
select
    case when HouseholdPointTotal < 1000 THEN 1 ELSE 0 END AS 'UNDER 1000'
    , case when HouseholdPointTotal >= 1000 AND HouseholdPointTotal < 2000 THEN 1 ELSE 0 END AS 'UPTO 2000'
    , case when HouseholdPointTotal >= 2000 AND HouseholdPointTotal < 3000 THEN 1 ELSE 0 END AS 'UPTO 3000'
    , case when HouseholdPointTotal >= 3000 AND HouseholdPointTotal < 4000 THEN 1 ELSE 0 END AS 'UPTO 4000'
    , case when HouseholdPointTotal >= 4000 AND HouseholdPointTotal < 5000 THEN 1 ELSE 0 END AS 'UPTO 5000'
    , case when HouseholdPointTotal >= 5000 AND HouseholdPointTotal < 6000 THEN 1 ELSE 0 END AS 'UPTO 6000'
    , case when HouseholdPointTotal >= 6000 AND HouseholdPointTotal < 7000 THEN 1 ELSE 0 END AS 'UPTO 7000'
    , case when HouseholdPointTotal >= 7000 AND HouseholdPointTotal < 8000 THEN 1 ELSE 0 END AS 'UPTO 8000'
    , case when HouseholdPointTotal >= 8000 AND HouseholdPointTotal < 9000 THEN 1 ELSE 0 END AS 'UPTO 9000'
    , case when HouseholdPointTotal >= 9000 AND HouseholdPointTotal < 10000 THEN 1 ELSE 0 END AS 'UPTO 10000'
from MRS_Retail_HouseholdPoints
) pts

1 个答案:

答案 0 :(得分:0)

不确定它是最好的还是最具可读性的方式,但是。

您可以选择1到10之间的数字。

你可以这样做

SELECT TOP 10 ROW_NUMBER() OVER (ORDER BY number)  rn
  FROM [master]..spt_values

现在,你用它构建一个CTE,它会给你一个下限和一个上限

(0-999,1000-1999,2000-2999)例如

with CTE as (select 
               (rn-1) * 1000 as low, 
               (rn * 1000)-1 as up 
             FROM (SELECT 
                    TOP 10 ROW_NUMBER() OVER (ORDER BY number)  rn
                  FROM [master]..spt_values ) 
             s)

当然,这个部分可以用包含数字或下限和上限的表来代替,这会使事情变得更少&#34;棘手&#34;而且更具可读性......

无论如何,你可以在你的桌子上进行左连接,并建立标签(与你的完全不同,但是...

所以

with CTE as (select 
              (rn-1) * 1000 as low, 
              (rn * 1000)-1 as up 
             FROM (SELECT 
                      TOP 10 ROW_NUMBER() OVER (ORDER BY number)  rn
                   FROM [master]..spt_values ) s
             )

  select  
   cast(low as varchar) + '-' + cast(up as varchar) as label,
   count(p.Id) as number  
  from cte c 
  left join MRS_Retail_HouseholdPoints p on p.HouseholdPointTotal between low and up
  group by  low, up

但是这将返回行,而不是列。

如果你想要列

,你需要转动
with CTE as (select 
               (rn-1) * 1000 as low, 
                (rn * 1000)-1 as up 
             FROM (SELECT 
                     TOP 10 ROW_NUMBER() OVER (ORDER BY number)  rn
                   FROM [master]..spt_values ) 
                     s)
      select [0-999], [1000-1999], [2000-2999], [3000-3999], [4000-4999], [5000-5999], [6000-6999]--etc.
      from
      (select  
       cast(low as varchar) + '-' + cast(up as varchar) as label,
       count(p.Id) as nb
      from cte c 
      left join MRS_Retail_HouseholdPoints p on p.HouseholdPointTotal between low and up
      group by  low, up) p
      PIVOT (min(nb)
             FOR label in (for label in ([0-999], [1000-1999], [2000-2999], [3000-3999], [4000-4999], [5000-5999], [6000-6999]--etc))
    as  pvt

不那么可读,呵呵;)

如果您想避免编写上下限,您甚至可以进行动态调整。