您的编程逻辑似乎没问题,但是 SQL 语句需要一些工作。似乎您是 SQL 新手,正如您所指出的,您似乎不了解 JOIN 是什么。
您正在尝试从名为 POST、TAG1、TAG2 和 TAG3 的 4 个表中选择数据。
我不知道这些表中有什么,如果没有这些信息,很难给出示例 SQL 语句。所以,我要编造一些东西,只是为了讨论的目的。假设表 POST 有 6 列,其中有 8 行数据。
P Fname Lname Country Color Headgear
- ----- ----- ------- ----- --------
1 Alex Andrews 1 1 0
2 Bob Barker 2 3 0
3 Chuck Conners 1 5 0
4 Don Duck 3 6 1
5 Ed Edwards 2 4 2
6 Frank Farkle 4 2 1
7 Geoff Good 1 1 0
8 Hank Howard 1 3 0
我们会说 TAG1、TAG2 和 TAG3 是查找表,每个表只有 2 列。表 TAG1 有 4 个国家代码:
C Name
- -------
1 USA
2 France
3 Germany
4 Spain
表 TAG2 有 6 个颜色代码:
C Name
- ------
1 Red
2 Orange
3 Yellow
4 Green
5 Blue
6 Violet
表 TAG3 有 4 个头饰代码:
C Name
- -------
0 None
1 Glasses
2 Hat
3 Monacle
现在,当您从这 4 个表中选择数据时,对于 P=6,您正试图获得如下结果:
Fname Lname Country Color Headgear
----- ------ ------- ------ -------
Frank Farkle Spain Orange None
首先,让我们看看你的 WHERE 子句:
where t.name = ?, u.name = ?, v.name = ?
抱歉,这样使用逗号是一个语法错误。通常你只想找到所有三个条件都为真的数据;你可以使用 AND 来做到这一点:
where t.name=? AND u.name=? AND v.name=?
其次,为什么要将表连接在一起?因为你需要更多信息。表 POST 说 Frank 的 COUNTRY 值为 4;表 TAG1 说 4 表示西班牙。所以我们需要将这些表“连接”在一起。
连接表的古老(我认为是 1980 年之前)方法是在 FROM 子句中列出多个表名,用逗号分隔。这给了我们:
SELECT P.FNAME, P.LNAME, T.NAME As Country, U.NAME As Color, V.NAME As Headgear
FROM POST P, TAG1 T, TAG2 U, TAG3 V
这个查询的问题在于你没有告诉它你想要哪些行,或者它们是如何相互关联的。所以数据库生成了一个叫做“笛卡尔积”的东西。你想要一个笛卡尔积是非常罕见的——通常这是一个巨大的错误。即使您的数据库中只有 22 行,此 SELECT 语句将返回 768 行数据:
Alex Andrews USA Red None
Alex Andrews USA Red Glasses
Alex Andrews USA Red Hat
Alex Andrews USA Red Monacle
Alex Andrews USA Orange None
Alex Andrews USA Orange Glasses
...
Hank Howard Spain Violet Monacle
没错,它会返回 4 个表中所有可能的数据组合。想象一下,POST 表最终增长到 20000 行,三个 TAG 表各有 100 行。整个数据库将不到一兆字节,但笛卡尔积将有 20,000,000,000 行数据——可能大约 120 GB 的数据。任何数据库引擎都会对此感到窒息。
因此,如果您想使用古老的方式来指定表,确保您的 WHERE 子句显示您正在查询的每个表之间的关系是非常重要的。这更有意义:
SELECT P.FNAME, P.LNAME, T.NAME As Country, U.NAME As Color, V.NAME As Headgear
FROM POST P, TAG1 T, TAG2 U, TAG3 V
WHERE P.Country=T.C AND P.Color=U.C AND P.Headgear=V.C
这只会返回 8 行数据。
使用古老的方式,很容易意外创建笛卡尔积,这几乎总是不好的。所以他们修改了 SQL 使其更难做。这就是 JOIN 关键字。现在,当您指定其他表时,您可以同时指定它们的关联方式。新方法是:
SELECT P.FNAME, P.LNAME, T.NAME As Country, U.NAME As Color, V.NAME As Headgear
FROM POST P
INNER JOIN TAG1 T ON P.Country=T.C
INNER JOIN TAG2 U ON P.Color=U.C
INNER JOIN TAG3 V ON P.Headgear=V.C
您仍然可以使用 WHERE 子句。
SELECT P.FNAME, P.LNAME, T.NAME As Country, U.NAME As Color, V.NAME As Headgear
FROM POST P
INNER JOIN TAG1 T ON P.Country=T.C
INNER JOIN TAG2 U ON P.Color=U.C
INNER JOIN TAG3 V ON P.Headgear=V.C
WHERE P.P=?
如果你调用它并传入值 6,你只会返回一行:
Fname Lname Country Color Headgear
----- ------ ------- ------ --------
Frank Farkle Spain Orange None