如何聚合SQL中字符串列的数字

时间:2014-02-15 02:20:08

标签: sql sql-server group-by aggregate

我正在处理设计糟糕的数据库列,其中包含类似

的值
ID  cid   Score
1    1    3 out of 3
2    1    1 out of 5
3    2    3 out of 6
4    3    7 out of 10

我希望得分列的总和和百分比分组在cid上,如此

cid    sum            percentage
1      4 out of 8       50
2      3 out of 6       50
3      7 out of 10      70  

我该怎么做?

2 个答案:

答案 0 :(得分:1)

您可以尝试这种方式:

select
  t.cid
  , cast(sum(s.a) as varchar(5)) + 
      ' out of ' + 
      cast(sum(s.b) as varchar(5)) as sum
  , ((cast(sum(s.a) as decimal))/sum(s.b))*100 as percentage
from MyTable t
  inner join 
  (select
    id
    , cast(substring(score,0,2) as Int) a
    , cast(substring(score,charindex('out of', score)+7,len(score)) as int) b
   from MyTable
   ) s on s.id = t.id
group by t.cid

[SQLFiddle Demo]

答案 1 :(得分:0)

重新设计表格,但作为CTE即时进行。这里的解决方案并不像你能做到的那么短,但它利用了方便的SQL Server函数PARSENAME。如果要截断而不是舍入,或者如果希望它是十进制值而不是int,则可能需要调整百分比计算。

在此解决方案或大多数解决方案中,您必须指望分数的列值采用您显示的特定格式。如果你有任何疑问,你应该进行一些其他检查,这样你就不会错过或误解任何东西。

with
P(ID, cid, Score2Parse) as (
  select
    ID,
    cid,
    replace(Score,space(1),'.')
  from scores
),
S(ID,cid,pts,tot) as (
  select
    ID,
    cid,
    cast(parsename(Score2Parse,4) as int),
    cast(parsename(Score2Parse,1) as int)
  from P
)
  select
    cid, cast(round(100e0*sum(pts)/sum(tot),0) as int) as percentage
  from S
  group by cid;