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

SQL从多个表中进行选择,并在其中一个表中应用不同的条件,sql,select,Sql,Select,SQL从多个表中进行选择,并在其中一个表中应用不同的条件 第一张表: Student Name | Student ID -------------------------- John Smith | 1 Marry Johnson | 2 第二张表: Student ID | Year | Enrollment date ----------------------------------- 1 | 2013 | 2013-10-01 1 | 2

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
+
表2
的注册日期中获取同一年上过
数学
艺术
课程的学生名单

 Student Name | Year | Enrollment date
 -------------------------------------
   John Smith | 2013 | 2013-10-01
Marry Johnson | 2014 | 2014-02-01
或者,如果这是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的意思是:

让我看看有班级的学生(在提供的班级列表中),他们在同一年中没有注册未尝试以下方法:

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

小提琴:

如果我的评论是正确的,你想要的是让学生们一起上课,那么这将为你提供一个列表。但是,我仍然不确定您是如何链接到注册日期表的

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
从中选择t1a.[student name]作为Student1,t1b.[student name]作为Student2
第三表t3a
内部连接t3a上的第三个表t3b。[学生ID]1

决定使用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

哪个数据库-oracle、mysql、sql server?约翰·史密斯不是在2013年上数学课,在2014年上艺术课吗?这与你的要求相矛盾,因为那不是同一年的事@ericpap我想他想要的是Marry和John在同一年上数学课,在同一年上艺术课,所以把他们两个都还给我。@ericpap-我猜他可能是指谁在同一年上数学课,谁在同一年上艺术课等等……第二张表对你的成绩没有意义。为什么一个学生的日期要早一点,另一个学生的日期要晚一点?我正在考虑一个类似的解决方案,我认为这会奏效。然而,我很想知道,如果他需要在名单中包括第三(或第四,或第十)个班级,你会提出什么建议。添加更多的联接最终将变得禁止……谢谢,这真的很有帮助;)我只是想知道如果我想在第三个表中添加第二个标准,第二个示例如何扩展,例如,不仅是“类”,而且是“级别”(作为一个单独的列)?在您的情况下,没有匹配项,因为您提出的问题与数据相矛盾,所以我假设它是打字错误。
 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