我必须为我的学校创建一个数据库,现在我有这三个表:
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
。
答案 0 :(得分:3)
您的查询出了什么问题首先是没有关联外部Note
和Examination
表的条件。
此外,这两个表之间没有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'
;
我抱歉没有提供SQLite示例 - 我没有安装Web SQLite,并且javascript SQLite版本的加载非常非常慢。
虽然IN (subquery or correlated subquery)
语法在一个方面可以更容易理解,但根据我的经验,它的使用往往会影响人的概念,并妨碍普通的基本JOIN
思考。我建议您尽可能使用JOIN
并默认使用IN (subquery)
。如果您可以这样做,您将能够理解IN
查询。但它似乎没有相反的方法。
使用ANSI JOIN
语法的一个巨大好处是,如果您没有ON
子句,则查询将不会运行。它进一步为需要它们的表提供条件而不是远离WHERE
子句,另外,它逻辑地分离被认为是基本JOIN
一部分的部分(这些表将始终使用)以及被视为此特定查询的特殊WHERE
过滤器的部分。
答案 1 :(得分: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'