SQL从多个表中进行选择,并在其中一个表中应用不同的条件
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
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