本周我正在研究多个表连接,并返回一些奇怪的结果。这是场景......
使用正确的表格,使用传统的连接操作创建查询,该操作将列出客户的姓名,书名和订单日期(格式为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');
任何人对我在这里失踪的事情都有任何想法吗?
感谢。
答案 0 :(得分:9)
我建议您现在养成使用ANSI样式联接的习惯,这意味着您应该使用INNER JOIN
,LEFT OUTER JOIN
,RIGHT OUTER JOIN
,FULL 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
子句,使语句更易读,更易于调试。