0

我有一张看起来像这样的桌子

Subject    Mark    Girls      Boys

Math        85      4          6
Math        86      1          3
Math        87      1          9
Math        92      2          9
Math        96      9          4
English     83      4          5
English     87      2          4 
English     91      2          3
English     99      4          1

我希望将这些数据插入到另一个看起来像的表中

Subject    Range    Girls    Boys
Math       80-89    6         19
Math       90-99    11        13
English    80-89    6         9
English    90-99    6         4

假设只有两位数的分数,我的查询应该是什么来完成这个。我尝试了一个很幼稚的方法GROUP BYIF MARK like 1%但失败得很惨。

4

4 回答 4

1

您可以使用CASE表达式来创建范围。如果您有更多范围,则将它们添加到CASE

select subject,
  case 
    when mark >= 80 and mark <= 89 then '80-89'
    when mark >= 90 and mark <= 99 then '90-99'
  end `Range`,
  sum(girls) Girls,
  sum(boys) Boys
from yourtable
group by subject, case 
    when mark >= 80 and mark <= 89 then '80-89'
    when mark >= 90 and mark <= 99 then '90-99'
  end
order by subject

请参阅SQL Fiddle with Demo

如果您不想在 中重复CASEGROUP BY则可以使用子查询:

select subject, 
  `range`,
  sum(girls) girls,
  sum(boys) boys
from
(
  select subject,
    case 
      when mark >= 80 and mark <= 89 then '80-89'
      when mark >= 90 and mark <= 99 then '90-99'
    end `Range`,
    girls,
    boys
  from yourtable
) src
group by subject, `range`
order by subject

请参阅SQL Fiddle with Demo

我建议您考虑创建一个开始/结束范围类似于此的表:

create table mark_ranges
(
  start_range int,
  end_range int
);

insert into mark_ranges values
(0, 9),
(10, 19),
(20, 29),
(30, 39),
(40, 49),
(50, 59),
(60, 69),
(70, 79),
(80, 89),
(90, 99);

创建表格后,通过加入表格来获取范围非常容易:

select subject,
  `range`,
  sum(girls) girls,
  sum(boys) boys
from
(
  select t.subject,
    concat(r.start_range, '-', r.end_range) `range`,
    t.girls,
    t.boys
  from yourtable t
  inner join mark_ranges r
    on t.mark >= r.start_range
    and t.mark <= r.end_range
) src
group by subject, `range`

请参阅带有演示的 SQL Fiddle

于 2013-03-06T15:34:43.263 回答
1

这是一个查询,它将自动定义标记范围并产生所需的结果:

SELECT 
  Subject, 
  CONCAT(MarkMin, '-', MarkMax),  
  (
    SELECT SUM(Girls) 
    FROM yourtable 
    WHERE Subject = Marks.Subject AND Mark >= MarkMin AND Mark <= MarkMax
  ) AS Girls,
  (
    SELECT SUM(Boys) 
    FROM yourtable 
    WHERE Subject = Marks.Subject AND Mark >= MarkMin AND Mark <= MarkMax
  ) AS Boys
FROM
(
SELECT
    Subject,
    ROUND(TRUNCATE(Mark/10,0),0) * 10 AS MarkMin,
    ROUND(TRUNCATE(Mark/10,0),0) * 10 + 9 AS MarkMax
FROM yourtable
GROUP BY Subject, MarkMin
) Marks;

演示

于 2013-03-06T16:19:07.997 回答
0

这是实现您的结果的 TSQL:

select
    Subject,
    Range,
    Girls = Sum(Girls),
    Boys  = Sum(Boys)
from (
    values('80-89', 80, 89),
          ('90-99', 90, 99)
) T(Range, MinValue, MaxValue)
left join Data on Data.Mark between T.MinValue and T.MaxValue
group by Subject, Range
于 2013-03-06T15:36:39.963 回答
0

这是一个如何执行此操作的示例。我使用了 SQL Server 2008 你可以用你的确切问题修改查询,但我给出了想法。如果这解决了您的问题,请将答案标记为已接受。

-- sample: marks table
create table marks(sj varchar(200), mark  int, girl int, boy int)

-- insert some data
insert into marks values ('eng', 85, 2, 3)
insert into marks values ('eng', 86, 3, 4)
insert into marks values ('eng', 95, 4, 5)
insert into marks values ('eng', 95, 5, 6)

-- check data
select * from marks

-- create range table
create table marks_range(sj varchar(200), range varchar(200), girl int, boy int)

--now enter the ranges one by one

--80-89
insert into marks_range 
select sj, '80-89', SUM(girl), SUM (boy) from marks where mark < 90 and mark >= 80
group by sj

--90-99
insert into marks_range 
select sj, '90-99', SUM(girl), SUM (boy) from marks where mark < 100 and mark >= 90
group by sj

-- check result
select * from marks_range
于 2013-03-06T15:43:09.767 回答