我正在使用SQL Server学习数据库,而重复操作使我感到困惑:
SELECT t.tno, t.tname, classes = (SELECT COUNT(*) FROM teaching te WHERE te.tno = t.tno)
FROM teacher t, teaching t2
WHERE t.tno = t2.tno AND t2.Llanguage = 'English'
如果我使用上面的代码,则会得到包含许多重复行的结果,如下所示:
+------+----------+-------+
|tno |tname |classes|
+------+----------+-------+
|T01 |t1 |3 |
|T01 |t1 |3 |
|T03 |t3 |4 |
|T03 |t3 |4 |
|T03 |t3 |4 |
|T04 |t4 |3 |
|T05 |t5 |3 |
|T05 |t5 |3 |
+------+----------+-------+
但是,如果我不使用子查询,则不会发生重复。有人可以帮我吗?
更新10/14 :teacher
和teaching
中的数据:
teacher:
+------+----------+---+----------+--------------------+
|tno |tname |sex|birthday |title |
+------+----------+---+----------+--------------------+
|T01 |t1 |m |1980-06-10|lecturer |
|T02 |t2 |f |1970-03-14|professor |
|T03 |t3 |m |1973-04-20|associate professor |
|T04 |t4 |m |1981-08-30|lecturer |
|T05 |t5 |f |1975-07-20| associate professor|
|T06 |t6 |m |1980-09-19|lecturer |
+------+----------+---+----------+--------------------+
teaching:
+------+------+----------+----+
|tno |cno |Llanguage |Year|
+------+------+----------+----+
|T01 |801 |English |2018|
|T01 |803 |Bilingual |2018|
|T01 |804 |English |2018|
|T02 |801 |Bilingual |2018|
|T02 |804 |Bilingual |2018|
|T03 |802 |English |2018|
|T03 |804 |Bilingual |2018|
|T03 |805 |English |2018|
|T03 |806 |English |2018|
|T04 |802 |Bilingual |2018|
|T04 |803 |English |2018|
|T04 |805 |Bilingual |2018|
|T05 |801 |Bilingual |2018|
|T05 |802 |English |2018|
|T05 |803 |English |2018|
|T06 |803 |Bilingual |2018|
|T06 |806 |Bilingual |2018|
+------+------+----------+----+
对于加入样式,我的老师使用的幻灯片非常过时(也许是10年前?)。实际上,代码是几周前编写的,现在我已经习惯了使用inner join
。但是,我仍然对这个问题感到困惑。
答案 0 :(得分:1)
由于教师可以教多个英语课,因此您会得到重复。您会向每位老师展示他们的英语课的次数。
查询应做的事情(或我应做的假设):显示所有教至少一门英语课的老师及其整体班数。 “至少教一门英语课”的条件是可以在汇总教师行后检查的条件,因此可以将其放在HAVING
子句中。
select t.tno, t.tname, count(t2.tno) as classes
from teacher t
inner join teaching t2 on t.tno = t2.tno
group by t.tno, t.tname
having count(case when t2.language = 'English' then 1 end) > 0
我不知道SQL Server是否实际上在t.tname
子句中需要GROUP BY
。标准SQL则没有,因为t.tno
应该唯一地定义一位包括其姓名的教师。
正如其他人提到的那样:如果被教您使用逗号分隔的联接,那么最好退出您的课堂,教程或书本。
更新:您已经编辑了请求,但似乎仍然对联接的结果感到困惑。为了说明联接中发生了什么:
老师:
+------+----------+---+----------+--------------------+ |tno |tname |sex|birthday |title | +------+----------+---+----------+--------------------+ |T01 |t1 |m |1980-06-10|lecturer | |T02 |t2 |f |1970-03-14|professor | +------+----------+---+----------+--------------------+
教学:
+------+------+----------+----+ |tno |cno |Llanguage |Year| +------+------+----------+----+ |T01 |801 |English |2018| |T01 |803 |Bilingual |2018| |T01 |804 |English |2018| |T02 |801 |Bilingual |2018| |T02 |804 |Bilingual |2018| +------+------+----------+----+
老师参加了英语课:
+------+----------+------+-----------+--------------------+-------+-------+-------------+--------+ |t.tno |t.tname |t.sex |t.birthday |t.title |t2.tno |t2.cno |t2.Llanguage |t2.Year | +------+----------+------+-----------+--------------------+-------+-------+-------------+--------+ |T01 |t1 |m |1980-06-10 |lecturer |T01 |801 |English |2018 | |T01 |t1 |m |1980-06-10 |lecturer |T01 |804 |English |2018 | +------+----------+------+-----------+--------------------+-------+-------+-------------+--------+
其中将显示前两列以及tno的示教计数:
+------+----------+--------+ |t.tno |t.tname |classes | +------+----------+--------+ |T01 |t1 |3 | |T01 |t1 |3 | +------+----------+--------+
答案 1 :(得分:-1)
Left outer
或Inner only
。
除非您的表强制使用约束,否则请尽量不要使用inner joins
。SELECT t.tno, t.tname, classes = COUNT(*)
FROM teacher t
LEFT OUTER JOIN teaching t2 ON t.tno = t2.tno
WHERE t2.Llanguage = 'English' AND t2.tno IS NOT NULL
GROUP BY t.tno, t.tname