Oracle笛卡尔积与加入

时间:2013-01-31 14:38:50

标签: sql oracle join cartesian-product

在我的公司,我们使用Oracle数据库。我注意到每个人都写这样的问题:

SELECT p.name, p.id, o.issued_date
FROM orders o, products p
WHERE o.productid = p.id;

数据库在这种情况下做了什么?制作笛卡儿积,然后只选择某些行?这听起来不对。

3 个答案:

答案 0 :(得分:5)

  

数据库在这种情况下做了什么?

与指定ANSI连接时相同:

SELECT *
FROM orders o
JOIN products p ON o.productid = p.id
  

我注意到每个人都在写这样的查询[...]

看起来您公司的很多人在Oracle中拥有多年的经验!我打赌他们也使用(+)表示外连接。这是Oracle prior to the 9i release支持的唯一语法。

答案 1 :(得分:2)

实际上,这是内部连接的最古老的ANSI标准。其他回复中的人提到它不是ANSI语法,但它不太正确。构造如

SELECT p.name, p.id, o.issued_date
FROM orders o, products p
WHERE o.productid = p.id;

遵守ANSI 88标准的SQL(现在称为隐式连接表单)。然而,它已经被更新的ANSI 92显式形式的内部,外部和交叉连接取代:

-- Inner join
SELECT p.name, p.id, o.issued_date
FROM orders o [INNER] JOIN products p
ON o.productid = p.id
WHERE (residual conditions);

-- Outer joins:
SELECT p.name, p.id, o.issued_date
FROM orders o LEFT|RIGHT|FULL [OUTER] JOIN products p
ON o.productid = p.id
WHERE (residual conditions);

-- Explicit corss join:
SELECT p.name, p.id, o.issued_date
FROM orders o CROSS JOIN products p
WHERE (residual conditions);

这正是因为先前的语法误导并且容易出错,因为连接条件容易与残留条件混合并且可能被错误地丢失。这就是强烈建议使用显式语法的原因。

方括号[]表示'noise'(可选)关键字,竖线条|表示'或'(您可以放置​​LEFT或RIGHT或FULL,而不是全部)。我希望这会有所帮助。

答案 2 :(得分:0)

就是这样:

SELECT 
     *
FROM 
     Orders o
INNER JOIN 
     Products p
ON
     p.id=o.ProductID

请注意,您永远不应SELECT *...列出您需要的列。您还应该明确说明连接的类型(内部,左侧,右侧,外侧)。这是实现连接的正确方法,是ANSI语法。