【问题标题】:Generate summary data based on configuration table in SQL Server根据 SQL Server 中的配置表生成汇总数据
【发布时间】:2012-09-26 12:26:55
【问题描述】:

我正在尝试从 SQL Server 2008 中的分数列表生成摘要。
我有两张桌子:SQL Fiddle link

ScorePerson 表包含人的 ID 和他们的分数,从 -5 到 15。我的 SQL/存储过程的最终用户需要创建如下摘要:

Scoreband| TotalNoOfPeople | AvgScore
--------------------------------
-5 to 0  | 2               | -2
0 to 5   | 3               |  2
5 to 10  | 2               |  8
10 to 15 | 3               | 13.3

最终用户应该可以从ScoreMinMax 表中配置分数范围,即最小值和最大值。

我曾尝试使用 CASE stement 来实现这一点,但它会将摘要生成为列。我可能需要旋转它或从多个选择语句中使用 UNION。但如果ScoreMinMax 表中添加了新行,这种方法似乎无法扩展。 到目前为止,我能够使用 CROSS JOINT 获得与上面示例类似的一些结果,但它并不总是产生正确的结果。

有人能指出我如何实现这一目标的正确方向吗?

SQL Fiddle link

ScorePerson - contains actual scores

ScoreMinMax - the configuration for min and max score bands

【问题讨论】:

  • 您是否想要一个查询,该查询将生成从 ScorePerson 单独选择一个类似于表 ScoreMinMax 的结果集?
  • 你如何处理重叠值 0,5,10...?
  • 您可以设置最小值和最大值,例如 -5 到 0、1 到 5、6 到 10 等等,或者按照 podiluska 的建议进行操作。

标签: sql sql-server-2008 tsql summary


【解决方案1】:

您可以使用聚合函数:

select title ScoreBand,
  count(*) TotalNoPeople, 
  avg(p.score) AvgScore  
from scoreperson p
inner join scoreminmax m
  on p.score between m.minscore and m.maxscore
group by Title
order by cast(left(title, 2) as int) 

SQL Fiddle with Demo

如果您在现有范围内没有人,您可以这样:

select case when title is not null 
            then title
            else 'No Range' end ScoreBand,
  count(personid) TotalNoPeople, 
  avg(p.score) AvgScore  
from scoreperson p
left join scoreminmax m
  on p.score between m.minscore and m.maxscore
group by id, Title
order by id

SQL Fiddle with Demo

编辑 #2,根据您可以使用的 cmets:

select m.title ScoreBand,
  count(p.personid) TotalNoPeople, 
  avg(p.score) AvgScore  
from scoreminmax m
left join scoreperson p
  on p.score between m.minscore and m.maxscore
group by m.id, m.Title
order by m.id;

SQL Fiddle with Demo

【讨论】:

  • 太好了,谢谢。万一没有人落在给定的分数范围内。是否仍然可以输出 0 TotalNoPeople 的乐队,而不是根本不显示?
  • @Sivakanesh 请参阅下面的答案。
  • 对不起,我的意思是,如果说 ScoreBand '-5 to 0' 里面没有任何一个。而不是不显示乐队,我想说 -count for '5 to 0' 是 0。sqlfiddle.com/#!3/0b775/6
  • @Sivakanesh 好的,但是如果有超出表格范围的分数,您是否要显示任何内容?
  • 不,在这种情况下不需要。
【解决方案2】:

试试

Select Title, count(personid), AVG(score)
from 
    scoreminmax  
    left join scoreperson 
    on scoreperson.score>=minscore 
    and scoreperson.score<maxscore 
group by ID,title 
order by ID 

请注意,我只在其中一个组中包含了边界 (0,5,10) 的分数。

【讨论】:

    【解决方案3】:
    select smm.Title Scoreband, count(*) TotalNoOfPeople, avg(sp.Score) AvgScore
    from 
        ScorePerson sp
        inner join
        ScoreMinMax smm on sp.Score >= smm.MinScore and sp.Score < smm.MaxScore
    group by smm.Title
    

    【讨论】:

      猜你喜欢
      • 2021-06-28
      • 1970-01-01
      • 2019-06-12
      • 2020-05-16
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      • 1970-01-01
      • 2015-03-02
      相关资源
      最近更新 更多