我正在尝试做
select *
from buildings
where levels = 3
join managers;
但它在加入时说错误。我想将建筑物的 id 与 manager 表中的 id 匹配,所以我想我想要自然加入。
我正在尝试做
select *
from buildings
where levels = 3
join managers;
但它在加入时说错误。我想将建筑物的 id 与 manager 表中的 id 匹配,所以我想我想要自然加入。
如果您将 JOIN 放在正确的位置(在 FROM 和 WHERE 之间)并且在没有 ON 的情况下编写 JOIN 是合法的,那么结果将是一个交叉连接 - 然后您在 WHERE 中过滤的笛卡尔积。
这是一件完全有效的事情,尽管在这种情况下可能不是您想要的。它可以通过在FROM
子句中添加逗号分隔的表来实现,例如:
FROM buildings, managers
当您打算在一个条件下连接两个表时,编写显式内部连接通常会更好:
SELECT *
FROM buildings b INNER JOIN managers m ON (b.manager_id = m.manager_id)
WHERE b.levels = 3;
...因为它使阅读该语句的其他人清楚地知道该ON
子句是一个连接条件,并且bl.levels=3
是一个过滤器。SQL 实现通常不关心,很可能将上述内容转换为:
SELECT *
FROM buildings b, managers m
WHERE b.levels = 3 AND b.manager_id = m.manager_id;
无论如何在内部,但是当使用显式连接语法编写具有许多连接的复杂查询时,更容易(IMO)理解它们。
还有另一种写你想要的方法,但它很危险,不应该使用 IMO:
SELECT *
FROM buildings bl
NATURAL JOIN managers m
WHERE bl.levels = 3;
在任何名称相同的列上加入。调试是一场噩梦,您必须查找表结构才能了解它的作用,如果有人重命名列,它就会中断,而且很痛苦。不使用。请参阅PostgreSQL 手册中的表表达式。
更可接受的是USING
上面讨论的语法:
SELECT *
FROM buildings bl
INNER JOIN managers m USING (manager_id)
WHERE bl.levels = 3;
它匹配两个列中命名manager_id
的列和JOIN
它们上的 s,将它们组合成一个列,但不像NATURAL JOIN
这样做是明确的并且没有可怕的魔法。
我仍然更喜欢写作INNER JOIN ... ON (...)
,但使用它是合理的,USING
而且,IMO,永远不会合理使用NATURAL
.
测试表结构为:
create table managers ( manager_id integer primary key );
create table buildings (
manager_id integer references manager(manager_id),
levels integer
);
JOIN
运算符应用于表,您应该在FROM
子句中提供它。如果你这样做,你会得到一个新的错误,声称没有JOIN
条件,因为你必须JOIN
在子句之后提供条件ON
(它不是可选的):
SELECT *
FROM buildings b JOIN managers m ON b.managerid = m.id
WHERE b.levels = 3
如果你想这样做,你必须写这样的东西:
select *
from bulidings b
join managers m on b.id=m.id
where levels = 3
然而,这个请求似乎很奇怪,我相信其中一个应该有一个外键进入另一个。所以更合适的查询是:
select *
from buidings b
join managers m on b.id = m.building_id //// or b.manager_id = m.id
where levels = 3
我认为你写的哪个查询是错误的。
所以请试试这个
select * from buildings as bl
join managers as mn on bl.F_ManagerID = mn.ManagerID
where bl.levels = 3
我想这会帮助你...