1

我正在尝试做

select * 
from buildings 
where levels = 3 
join managers;

但它在加入时说错误。我想将建筑物的 id 与 manager 表中的 id 匹配,所以我想我想要自然加入。

4

4 回答 4

2

如果您将 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
);
于 2012-09-23T23:47:11.597 回答
1

JOIN运算符应用于表,您应该在FROM子句中提供它。如果你这样做,你会得到一个新的错误,声称没有JOIN条件,因为你必须JOIN在子句之后提供条件ON(它不是可选的):

SELECT * 
FROM  buildings b JOIN managers m ON b.managerid = m.id
WHERE b.levels = 3 
于 2012-09-23T10:11:17.317 回答
0

如果你想这样做,你必须写这样的东西:

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
于 2012-09-23T10:12:02.607 回答
-1

我认为你写的哪个查询是错误的。

所以请试试这个

 select * from buildings as bl
    join managers as mn on bl.F_ManagerID = mn.ManagerID
    where bl.levels = 3

我想这会帮助你...

于 2012-09-23T10:14:14.130 回答