2012-09-23 205 views
1

我试图做JOIN语句不where子句

select * 
from buildings 
where levels = 3 
join managers; 

工作,但它在加入说错误。我想匹配建筑物的id和manager表中的id,所以我想我想要自然连接。

+1

这是因为语法是错误的。 http:// www.w3schools.com/sql/sql_join_inner.asp' –

+0

内连接是什么SQL调用关系代数中的自然连接?我认为join会自动加入两个表中同名的属性中。 – Celeritas

+1

@LewsTherin:请不要链接到http://w3fools.com/,他们是一个糟糕的信息来源,它已经争取谷歌的排名达到顶峰。在这种情况下,[SELECT中的PostgreSQL文档](http://www.postgresql.org/docs/current/static/sql-select.html)将会是一个更好的参考。 –

回答

2

如果你把在正确的地方的JOIN(FROM和WHERE之间),它是合法的写JOIN如果没有,那么结果将是一个交叉连接 - 一个笛卡尔积,然后你在哪里过滤。

这是一个非常有效的事情,尽管在这种情况下可能不是你想要的。它可以通过添加逗号分隔的表到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)了解复杂的查询有许多的时候,他们正在使用显式连接语法编写连接。

还有另外一种方式来写你想要什么,但它的危险和国际海事组织不应使用:

SELECT * 
FROM buildings bl 
NATURAL JOIN managers m          
WHERE bl.levels = 3; 

这JOIN的任何列that're名称相同。调试是一场噩梦,你必须查看表结构来理解它的功能,如果有人重命名了某列,它就会中断,这很痛苦。不使用。见Table expressions in the PostgreSQL manual

更可接受的是USING语法还如上所述:

SELECT * 
FROM buildings bl 
INNER JOIN managers m USING (manager_id) 
WHERE bl.levels = 3; 

它匹配命名两列manager_idJOIN 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 
); 
+0

Hooray显式连接!无论如何,这通常是进行OUTER JOIN的唯一方式(除非,AFAIK,您使用的是Sybase或其衍生产品之一并具有'* =')。 –

+0

@ muistooshort Oracle有/也有疯狂的加入语法。他们使用了“(+)”来表示“顺便说一下,我在WHERE子句中提到的这个表的连接是一个外连接,而不是我告诉你的,而不是'FROM'条款”。 ANSI连接只出现在9i中,他们在那之前坚持自己奇怪的语法。请参阅http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:6585774577187,http://www.dba-oracle.com/tips_oracle_left_outer_join.htm –

1

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

SELECT * 
FROM buildings b JOIN managers m ON b.managerid = m.id 
WHERE b.levels = 3 
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 
-1

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

所以,请尽量将

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

我认为这将有助于你...

+0

这也是错误的 - 你尝试过吗?没有'=='运算符,而你的意思是'dl.F_ManagerID'不是'bl.F_ManagerID'。无论如何,IMO更清楚地写成“INNER JOIN ... ON”。 –

+0

谢谢你的建议。 – Rajpurohit