2010-11-16 163 views
3

我的头正在吸(愚蠢)尝试使用JOIN,WITHGROUP BY为我的相当常见的情况提出了一个解决方案 - 我只是无法环绕它。让我在你扔的例子马上:SQL每月加入和每月总计百分比

我有两个表(ColorCount和Colorname):

ColorCount: 
ColorID Count Date 
1  42 2010-09-07 
1  1  2010-09-08 
2  22 2010-09-14 
1  20 2010-10-10 
3  4  2010-10-14 

ColorName: 
ColorID Name 
1  Purple 
2  Green 
3  Yellow 
4  Red 

现在,我要的是加入ColorName表到ColorCount表格,将每月的所有颜色计数加起来,并计算每月总计的每个计数的百分比。表是胜于言:

Output: 
Month Color Count Percentage 
09 Purple 43 66% 
09 Green 22 33% 
09 Yellow 0  0% 
09 Red  0  0% 
10 Purple 20 83% 
10 Green 0  0% 
10 Yellow 4  16% 
10 Red  0  0% 

(请注意,每月的总数0965,因此66%Purple,也是0的为不存在的颜色):

我希望有人梦想在SQL,这是一件容易的事......

回答

3

这工作,有以下注意事项:

  • 日期时间值必须是迄今为止,只有
  • 只列出那些个月其上有任何数据
  • 我列出了每月的第一天,以防万一您的数据跨越多年(假设您不想从2009年1月起汇总数据与2010年1月的数据)
  • 准确的百分比列格式详细信息我留给你,我必须回来上班

代码:

;with cte (ColorId, Mth, TotalCount) 
as (select 
     ColorId 
     ,dateadd(dd, -datepart(dd, Date) + 1, Date) Mth 
     ,sum(Count) TotalCount 
     from ColorCount 
     group by ColorId, dateadd(dd, -datepart(dd, Date) + 1, Date)) 
select 
    AllMonths.Mth [Month] 
    ,cn.Name 
    ,isnull(AggData.TotalCount, 0) [Count] 
    ,isnull(100 * AggData.TotalCount/sum(AggData.TotalCount * 1.00) over (partition by AllMonths.Mth), 0) Percentage 
    from (select distinct Mth from cte) AllMonths 
    cross join ColorName cn 
    left outer join cte AggData 
    on AggData.ColorId = cn.ColorId 
    and AggData.Mth = AllMonths.Mth 
    order by AllMonths.Mth, cn.ColorId 
+0

分区的使用。太好了! – 2010-11-16 16:01:22

+0

是的,很好。必须得到一本关于MSSQL 2008的好书 – AlexanderMP 2010-11-16 16:20:43

+0

关于SimpleTalk的开窗技术的很好的讨论,请访问http://www.simple-talk.com/sql/learn-sql-server/working-with-window-functions-in-sql-服务器/?utm_source = simpletalk&utm_medium =电子邮件的主&=的utm_content WindowsFunction-20101101&utm_campaign = SQL – 2010-11-16 18:42:43

2
SELECT 
    [Month], 
    [Name], 
    [Count], 
    CASE WHEN TotalMonth=0 THEN 'INF' ELSE cast(round([Count],0)*100.0/TotalMonth,0) as int) + '%' END as [Percentage] 
FROM 
(
SELECT 
    [Months].[Month] as [Month], 
    CN.[Name], 
    isnull(CC.[Count],0) as [Count], 
    (SELECT SUM([Count]) FROM ColorCount WHERE 
      datepart(month,[Date])=datepart(month,CC.[Date]) 
    ) as [TotalMonth] 
FROM (SELECT DISTINCT datepart(month,[Date]) as [Month] FROM ColorCount) [Months] 
LEFT JOIN ColorName CN ON [Months].[Month]=datepart(month,CC.[Date]) 
LEFT JOIN ColorCount CC ON CN.ColorID=CC.ColorID 
) AS tbl1 
ORDER BY 
    [Month] ASC, 
    [Name] ASC 

类似的东西.... 它不会显示月份的前导零,但它真的很重要吗?

+0

很好的尝试,但百分比关闭。 – 2010-11-16 15:25:21

+0

更好,但你应该转换为浮动以避免舍入错误。 – 2010-11-16 15:28:32

+0

它也可以通过零异常产生除法,但为了避免这种情况,只需要很多打字。我会尽力整理出来。百分比呢?为什么关闭? – AlexanderMP 2010-11-16 15:32:13