0

我有一个表 A 和表 B

表 A

Student     Math    Science
1           65      38
2           72      99
3           83      85
4           95      91
5           49      20
6           60      80

表 B

Course      score_low   score_high  Mark
Math        0           50          D
Math        51          80          C
Math        81          90          B
Math        91          100         A
Science     0           50          D
Science     51          80          C
Science     81          90          B
Science     91          100         A

我想看到的是加入表 a 和表 B

Student     Math    Science     Math Mark   Science Mark
1           65      38          C           D
2           72      99          C           A
3           83      85          B           B
4           95      91          A           A
5           49      20          D           D
6           60      80          C           C
4

3 回答 3

5

你的部分问题是你tableA是非规范化的,你有一个单独的列MathScience。获得结果的一种方法是取消透视数据,tableA以便您可以轻松加入tableb. 根据课程名称和分数范围加入数据后,您可以使用带有 CASE 表达式的聚合函数在单独的列中获取最终结果:

select a.student,
  max(case when a.Course = 'math' then a.mark end) Math,
  max(case when a.Course = 'science' then a.mark end) science,
  max(case when a.Course = 'math' then b.mark end) MathMark,
  max(case when a.Course = 'science' then b.mark end) ScienceMark
from
(
  select student, math mark, 'Math' Course 
  from tablea
  union all
  select student, Science mark, 'Science' Course 
  from tablea
) a
inner join tableb b
  on a.Course = b.Course
  and a.mark >= b.score_low
  and a.mark <= b.score_high
group by a.student;

请参阅SQL Fiddle with Demo

或者这可以使用多个连接来编写tableb

select a.student,
  a.math,
  a.science,
  bMath.mark mathMark,
  bSci.mark ScienceMark
from tablea a
left join tableb bMath
  on a.math >= bMath.score_low
  and a.math <= bMath.score_high
  and bMath.course = 'Math'
left join tableb bSci
  on a.science >= bSci.score_low
  and a.science <= bSci.score_high
  and bSci.course = 'Science';

请参阅SQL Fiddle with Demo。两者都会给出结果:

| STUDENT | MATH | SCIENCE | MATHMARK | SCIENCEMARK |
-----------------------------------------------------
|       1 |   65 |      38 |        C |           D |
|       2 |   72 |      99 |        C |           A |
|       3 |   83 |      85 |        B |           B |
|       4 |   95 |      91 |        A |           A |
|       5 |   49 |      20 |        D |           D |
|       6 |   60 |      80 |        C |           C |
于 2013-08-12T21:40:55.403 回答
0

还没有尝试过,但是像这样

select *, 
(select Mark from tableB where course='Math' and score_low >= a.Math and score_high <= a.Math), 

(select Mark from tableB where course='Science' and score_low >= a.Math and score_high <= a.Math) 
 from tableA a
于 2013-08-12T21:43:05.117 回答
0

尝试这个:

select a.Student, a.Math, a.Science, bm.Mark as [Math Mark], bs.Mark as [Science Mark]
from TableA a 
    join TableB bm on a.Math between bm.score_low and bm.score_high
                and bm.Course = 'Math'
    join TableB bs on a.Science between bs.score_low and bs.score_high
                and bs.Course = 'Science'
order by a.Student;

这是用 T-SQL 编写的,与 SQL Server 上使用的一样。如果您的 SQL 版本没有 between 子句,您可以将代码更改为:

    join TableB bm on a.Math >= bm.score_low 
                and a.Math <= bm.score_high
                and bm.Course = 'Math'
    join TableB bs on a.Science >= bs.score_low
                and a.Science <= bs.score_high
                and bs.Course = 'Science'

但是,我注意到数学和科学的成绩范围是相同的。这些范围会改变吗?如果不是,或者至少不经常,使用 case 语句会更容易:

select a.Student, a.Math, a.Science, 
    case 
        when a.Math between 0 and 50 then 'D'
        when a.Math between 51 and 80 then 'C'
        when a.Math between 81 and 90 then 'B'
        when a.Math between 91 and 100 then 'A'
        else 'X'
    end as [Math Mark], 
    case 
        when a.Science between 0 and 50 then 'D'
        when a.Science between 51 and 80 then 'C'
        when a.Science between 81 and 90 then 'B'
        when a.Science between 91 and 100 then 'A'
        else 'X'
    end as [Science Mark]
from TableA a 
order by a.Student;
于 2013-08-12T22:11:02.223 回答