加入多个表 - Oracle

时间:2014-06-07 18:37:01

标签: sql oracle

本周我正在研究多个表连接,并返回一些奇怪的结果。这是场景......

使用正确的表格,使用传统的连接操作创建查询,该操作将列出客户的姓名,书名和订单日期(格式为MM / DD / YYYY,别名为“订购日期” “)所有已购买”印刷为美国“的书籍的客户。

对于我要查询的数据库,此查询的正确表是BOOK_CUSTOMER,BOOKS,BOOK_ORDER和PUBLISHER。我写的语句返回了我需要的信息,但它返回了近5900条记录。我不明白这是怎么回事。出版商Printing is Us在数据库中只列出了14本书,并且只有20个客户记录,所以即使每个客户都购买了每本Printing is Us书籍,也只能返回280条记录。但我无法弄清楚我的错误。我的发言如下:

SELECT bc.firstname, bc.lastname, b.title, TO_CHAR(bo.orderdate, 'MM/DD/YYYY') "Order Date", p.publishername
FROM book_customer bc, books b, book_order bo, publisher p
WHERE(publishername = 'PRINTING IS US');

任何人对我在这里失踪的事情都有任何想法吗?

感谢。

3 个答案:

答案 0 :(得分:9)

我建议您现在养成使用ANSI样式联接的习惯,这意味着您应该使用INNER JOINLEFT OUTER JOINRIGHT OUTER JOINFULL OUTER JOIN和SQL语句中的CROSS JOIN元素,而不是使用“旧式”连接,其中所有表在FROM子句中一起命名,并且所有连接条件都放在{{1子句。与“旧式”连接相比,ANSI样式连接更容易理解,并且不太可能被误写和/或误解。

我将您的查询重写为:

WHERE

分享并享受。

答案 1 :(得分:2)

您正在进行笛卡尔加入。这意味着,如果你甚至没有单一的where子句,你获得的结果数量将是book_customer大小乘以book_order大小乘以book_order大小乘以发布商大小。

换句话说,结果集会因为你没有添加有意义的join子句而被炸毁。您的正确查询应如下所示:

SELECT bc.firstname, bc.lastname, b.title, TO_CHAR(bo.orderdate, 'MM/DD/YYYY') "Order Date", p.publishername
FROM book_customer bc, books b, book_order bo, publisher p
WHERE bc.book_id = b.book_id
AND bo.book_id = b.book_id
(etc.)
AND publishername = 'PRINTING IS US';

注意:通常建议不要使用此查询中的隐式连接,而是使用INNER JOIN语法。但我假设,这种语法在你的学习材料中使用,所以我把它留在了。

答案 2 :(得分:1)

虽然以前的答案绝对正确,但我更喜欢使用JOIN ON语法来确保我知道如何加入以及在哪些字段中加入。它看起来像这样:

SELECT bc.firstname, bc.lastname, b.title, TO_CHAR(bo.orderdate, 'MM/DD/YYYY') "Order         Date", p.publishername
FROM books b
JOIN book_customer bc ON bc.costumer_id = b.book_id
LEFT JOIN book_order bo ON bo.book_id = b.book_id
(etc.)
WHERE b.publishername = 'PRINTING IS US';

此语法完全分离WHERE子句中的JOIN子句,使语句更易读,更易于调试。