SQL查询三个表

时间:2013-06-17 22:10:51

标签: sql sqlite android-sqlite

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

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

2 个答案:

答案 0 :(得分: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'
;

See a Live Demo at SQL Fiddle(SQL Server 2008版)

我抱歉没有提供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'