2

我必须为我的学校创建一个数据库,现在我有这三个表:

Note                               Examination               Subject
+------+------+------+--------+    +------+----+--------+    +------+----------+
| _idS | _idP | Note | Punkte |    | _idP | idF| Thema  |    | _idF |   Name   |
+------+------+------+--------+    +------+----+--------+    +------+----------+
|    1 |    2 |    4 |     55 |    |    1 |  2 | Test 1 |    |    1 | Englisch |
|    2 |    2 |    2 |     80 |    |    2 |  4 | Test 2 |    |    2 | Deutsch  |
|    3 |    2 |    1 |     95 |    |    3 |  4 | Test 3 |    |    3 | Mathe    |
|    1 |    3 |    1 |     90 |    +------+----+--------+    |    4 | Physik   |
+------+------+------+--------+                              +------+----------+

现在我想Notes从一个由他给出的特殊科目Name和一个由他给出的特殊学生中选择所有内容ID (_idS)。我尝试过这样的事情:

SELECT N._idP, N.Note, N.Punkte, E.Thema FROM Note N, Examination E 
WHERE  N._idS='1' AND N._idP=(
       SELECT E._idP FROM Examination E WHERE E.idF=(
              SELECT S._idF FROM Subject S WHERE S.Name='Physik')
       );

// N._idS=1 is the special pupil
// S.Name='Physik' is the special subject

但这不会导致正确的输出。为了让它更清楚一点:我想要这个输出:

+--------+--------+----------+---------+
| N._idP | N.Note | N.Punkte | E.Thema |
+--------+--------+----------+---------+
|      2 |      4 |       55 | Test 2  |
|      3 |      1 |       90 | Test 3  |
+--------+--------+----------+---------+

我的 SQL 语句有什么问题,我必须更改什么才能获得上述结果?所有开头带下划线的列名_都是PRIMARY KEYS. 其他都是FOREIGN KEYS

4

2 回答 2

3

您的查询有什么问题首先是没有关联外部NoteExamination表的条件。

此外,JOIN这两个表之间没有的事实被您使用旧式非 ANSI 连接语法的事实所掩盖——其中表以逗号分隔,连接条件在WHERE子句中。我建议您使用简单JOINs且无IN子句来解决此问题,此外,您还可以使用现代 ANSI 语法:

SELECT
   N._idP,
   N.Note,
   N.Punkte,
   E.Thema
FROM
   Note AS N
   INNER JOIN Examination AS E
      ON N._idP = E._idP
   INNER JOIN Subject AS S
      On E.idF = S._idF
WHERE
   N._idS = 1
   AND S.Name = 'Physik'
;

查看 SQL Fiddle 上的实时演示(SQL Server 2008 版本)

我很抱歉没有提供 SQLite 示例——我没有安装 Web SQLite,而且 javascript SQLite 版本的加载速度非常非常慢。

虽然IN (subquery or correlated subquery)语法在某个方面可能更容易理解,但根据我的经验,它的使用往往会在概念上影响人,并妨碍简单的旧基本JOIN思维。我鼓励您使用JOINs 并尽可能默认使用它们IN (subquery)。如果你能做到这一点,你也将能够理解IN查询。但它似乎并没有反过来工作。

使用 ANSIJOIN语法的一大好处是,如果您没有ON子句,查询将不会运行。它进一步将条件与需要它们的表放在子句中,而不是放在很远的地方WHERE,此外,它在逻辑上分离了被认为是基本部分的部分JOIN(这些表将始终使用)和被认为是特殊WHERE过滤器的部分对于这个特定的查询。

于 2013-06-17T22:24:35.920 回答
0

试试这个:

SELECT n."_idP", n."Nota", n."Punkte", e."Thema"
FROM "Note" n, "Examination" e, "Subject" s
WHERE n."_idS" = 1
AND n."_idP" =e."_idP"
AND e."idF" = s."idF"
AND s."Name" = 'Physik'
于 2013-06-17T22:54:49.897 回答