如何在另一个表的列中查找行值?

时间:2013-08-12 21:28:08

标签: sql

我有一张表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

3 个答案:

答案 0 :(得分: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 |

答案 1 :(得分: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

答案 2 :(得分: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;

这是用在SQL Server上使用的T-SQL编写的。如果您的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'

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

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;