SQL从多个表中进行选择,并在其中一个表中应用不同的条件

时间:2014-04-29 17:04:12

标签: sql select

SQL从多个表中选择并在其中一个表中应用不同的标准

第一张表:

 Student Name | Student ID
 --------------------------
   John Smith | 1
Marry Johnson | 2

第二张表:

Student ID | Year | Enrollment date
-----------------------------------
         1 | 2013 | 2013-10-01
         1 | 2014 | 2014-02-01
         2 | 2013 | 2013-10-01
         2 | 2014 | 2014-02-01

第三张表:

Student ID | Year | Class
---------------------------
         1 | 2013 | Math
         1 | 2013 | Spanish
         1 | 2013 | Art
         1 | 2014 | French
         2 | 2014 | Math
         2 | 2013 | Spanish
         2 | 2014 | Literature
         2 | 2014 | French
         2 | 2014 | Art

如何从[{1}}获取Name来自Table 1 + Year& Enrollment date Table 2的学生列表Math同年Art个课程?

 Student Name | Year | Enrollment date
 -------------------------------------
   John Smith | 2013 | 2013-10-01
Marry Johnson | 2014 | 2014-02-01

4 个答案:

答案 0 :(得分:0)

Select s.studentName, d.EnrollmentDate 
From firstTable s
   join thirdTable m 
       on m.StudentId = s.studentId
           and m.class = 'Math'
   join thirdTable 
       on a.StudentId = s.studentId
          and a.year = m.year              -- ensure that art is in same year as math
          and a.class = 'Art'
   join secondTable d
       on d.studentId = s.studentId
          and d.Year = m.year 

或者,如果这是最近发布的SQL Server (支持基于values子句的动态结果集)   - 这也解决了添加任意数量的附加类的问题

Select s.studentName, d.EnrollmentDate 
From firstTable s
   join secondTable d
       on d.studentId = s.studentId
          and d.Year = m.year 
Where Not exists 
    (Select * From (values ('Math'), ('Art')) c(class)
     where Not exists
         (Select * from thirdTable
          Where studentId = s.studentId
              and year = d.Year
              and class = c.class))
语法上,thios读作:

向我展示那些一个班级(在提供的班级列表中)的学生,他们在同一年注册

答案 1 :(得分:0)

试试这个:

SELECT ft.student_name, st.Year, st.Enrollment_date from first_table ft
inner join second_table st on(ft.student_id = st.student_id) 
inner join third_table tt 
on(ft.student_id = tt.student_id and tt.class = 'Art')
inner join third_table tt1 
on(ft.student_id = tt1.student_id and tt1.class = 'Math'
 and tt.year = tt1.year) where tt.year = st.year

小提琴:http://sqlfiddle.com/#!2/c9e5e/1/0

答案 2 :(得分:0)

如果我的评论是正确的,你想要的是让学生一起上课,那么这将有助于你获得一份清单。但是,我仍然不确定您如何链接到注册日期表。

select t1a.[student name] as Student1, t1b.[student name] as Student2 from
thirdtable t3a 
inner join thirdtable t3b on t3a.[Student ID]<t3b.[Student ID]
inner join firsttable t1a on t3a.[Student ID] = t1a.[Student ID]
inner join firsttable t1b on t1b.[Student ID] = t3b.[Student ID]
where t3a.class = t3b.class and t3a.year = t3b.year and t3a.class  in ('Art','Math')
group by t1a.[student name], t1b.[student name]
having count(*) > 1

答案 3 :(得分:0)

决定是否使用WHERE子句或JOIN有时会很棘手。如果您使用的是允许使用INTERSECT的SQL版本,那么您还有更多选择。我会尝试:

 select t1.name, t2.year, t2.enrollment_date
 from table_1 t1 join table_2 t2 on t1.student_id = t2.student_id and t1.year = t2.year
 join (
      select student_id, year from t3 where class = 'Math'
      intersect
      select student_id, year from t3 where class = 'Art'
      ) fred on t1.student_id = fred.student_id and t1.year=fred.year

内部选择在这里非常通用;如果你愿意,你可以添加很多其他课程。如果INTERSECT不适合您的风格,那么其他推荐的加入将起作用。不过,我建议单独使用t3表作为子选择,然后将结果连接到表1和表2,因为它可以节省一些混乱:

 select t1.name, t2.year, t2.enrollment_date
 from table_1 t1 join table_2 t2 on t1.student_id = t2.student_id and t1.year = t2.year
 join (
      select t3_math.student_id, t3_math.year from table_3 t3_math
           join table_3 t3_art on t3_math.id = t3_art.id and t3_math.year = t3_art.year
           where t3_art.class = 'Art' and t3_math.class = 'Math'
      ) fred on t1.student_id = fred.student_id and t1.year=fred.year