加入多个表 - Oracle

two*_*977 3 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');
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

Bob*_*ica 10

我建议你的习惯,现在,使用ANSI风格的连接,这意味着你应该使用的INNER JOIN,LEFT OUTER JOIN,RIGHT OUTER JOIN,FULL OUTER JOIN,和CROSS JOIN在SQL语句中的元素,而不是使用"旧式"加入其中,所有的表都命名在FROM子句中和所有连接条件一起放在WHERE子句中.与"旧式"连接相比,ANSI样式连接更容易理解,并且不太可能被误写和/或误解.

我将您的查询重写为:

SELECT bc.firstname,
       bc.lastname,
       b.title,
       TO_CHAR(bo.orderdate, 'MM/DD/YYYY') "Order Date",
       p.publishername
FROM BOOK_CUSTOMER bc
INNER JOIN books b
  ON b.BOOK_ID = bc.BOOK_ID
INNER JOIN  book_order bo
  ON bo.BOOK_ID = b.BOOK_ID
INNER JOIN publisher p
  ON p.PUBLISHER_ID = b.PUBLISHER_ID
WHERE p.publishername = 'PRINTING IS US';
Run Code Online (Sandbox Code Playgroud)

分享和享受.


wvd*_*vdz 3

您正在进行笛卡尔连接。这意味着,如果您甚至没有单个 where 子句,则获得的结果数将是 book_customer 大小乘以 books 大小乘以 book_order 大小乘以出版商大小。

换句话说,结果集会被放大,因为您没有添加有意义的连接子句。您的正确查询应该如下所示:

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';
Run Code Online (Sandbox Code Playgroud)

注意:通常建议不要像此查询中那样使用隐式连接,而是使用INNER JOIN语法。然而,我假设您的学习材料中使用了此语法,因此我将其保留下来。