创建一个表格,该表格将为我提供包含和不包含评论的书籍列表

时间:2017-08-23 18:47:26

标签: sql sql-server join foreign-keys left-join

我有以下代码用于创建书店的数据库:

create database Bookorama

use Bookorama

--Book table
create table Book
( 
    bookID int identity(1,1),
    bookName varchar(50) unique,
    price smallmoney,

    primary key (bookID)
);

--Customer table
create table Customer
(
    custID int not null identity (1,1),
    cName varchar(50),
    cemid varchar(50),

    primary key (custID)
);

-- Order table
create table Ordertable
(
    orderID int identity(1,1),
    custID int not null,
    bookID int not null,

    primary key (orderID),
    foreign key (custid) references Customer(custid),
    foreign key (bookID) references Book(bookid)
);

create table Reviews
(
    reviewID int identity (1,1) not null,
    custID int not null,
    bookID int not null,
    review varchar(50),

    primary key (reviewID),
    foreign key (custID) references Customer(custID),
    foreign key (bookID) references Book(bookID)
)

对于我的任务,我接到了以下任务:

  

编写一个查询,显示所有图书的列表,对于那些有评论的人,列出评论。

我完全糊涂了,并且不知道我将如何开始接近这一点。我没有意识到我可以使用的任何JOIN组合。我对SQL很新。令我兴奋的是,我必须访问这两个表以使用书籍ID检索书名,然后创建与其相应评论的关联。同时还列出了没有评论的书籍。

4 个答案:

答案 0 :(得分:1)

LEFT JOIN关键字返回左表(table1)中的所有记录,以及右表(table2)中的匹配记录。如果没有匹配,则结果从右侧为NULL。

例如在MSSQL上:

USE AdventureWorks2008R2;
GO
SELECT p.Name, pr.ProductReviewID
FROM Production.Product p
LEFT OUTER JOIN Production.ProductReview pr
ON p.ProductID = pr.ProductID

答案 1 :(得分:0)

出于好奇,这是家庭作业吗?

我将如何做,加入有关书籍匹配的评论:

SELECT Books.*, Reviews.review
FROM Books, Reviews
LEFT JOIN Book.bookID ON Reviews.bookID

如果您不想要没有评论的人,可以使用CTE使用WHERE子句对其进行过滤:

WITH CTE_Example
AS
(SELECT *, Reviews.review
FROM Books, Reviews
LEFT JOIN Book.bookID ON Reviews.bookID)

SELECT * FROM CTE_Example
WHERE review IS NOT NULL

SELECT *
FROM Books
LEFT JOIN Book.bookID ON Reviews.bookID
WHERE Reviews.review IS NOT NULL

根据Sean Lange,通过使用INNER JOIN跳过WHERE子句来简化查询

SELECT *
FROM Books
INNER JOIN Book.bookID ON Reviews.bookID

答案 2 :(得分:0)

只需选择bookName和评论即可。这将列出所有书籍及其评论,如果没有,则列出NULL。

SELECT bookName,
       review
  FROM book
  LEFT JOIN reviews
    ON book.bookID = reviews.bookID

答案 3 :(得分:0)

  
    

编写一个查询,显示所有图书的列表,对于那些有评论的人,列出评论。

  

您引用的问题陈述不明确。首先,它打算但不表达类似的东西,"显示(bookID,reviewID)行的列表......"。其次,它打算但不表达类似于" ...书中有该评论或书籍没有评论且评论ID是......"什么?你应该知道/猜测/决定完成这个......" NULL"?空字符串?谁知道,它不清楚。

或者他们可能想要"(bookName,review)行,其中一些具有该名称的书籍具有一些评论,其中文本是(列)评论或者没有评论和(列)评论是...&#34 ;. (请注意,"某些",不是""。)谁知道,它不清楚。

(这种邋iness渗透到数据库教学法和文化中。)

  

让我感到震惊的是,我必须访问这两个表以使用书籍ID检索书名,然后创建与其相应评论的关联。

这就是JOIN所做的。

一个表包含其值以某种方式相关/关联的行。我们可以用谓词来描述关系(发货)/关联 - 列参数化句子模板:

/*  the rows where
    book bookID has title bookName and costs $price
*/
select * from Book

在FROM中,每个参数表列都被重命名为以其表名/别名和点为前缀。然后INNER JOIN生成每个行的每个组合。当没有重复项时,INNER JOIN保存根据参数关联的连接/ AND关联的行。 ON和WHERE都修改FROM结果以返回通过它们的条件的连接/ AND关联的行。

...
FROM Book b JOIN Reviews r ON b.bookID = r.bookID
/*  the rows where
        book b.bookID has title b.bookName and costs $b.price
    AND review r.reviewID is by customer r.custID of book r.bookID with text r.review
    AND b.bookID = r.bookID
*/

SELECT添加&删除点前缀时删除列。当我们不想复制但可能会得到一些时,我们会使用DISTINCT。

/*  the rows where
    FOR SOME values for b.*, r.*,
        bookID = b.bookID AND reviewID = r.reviewID
    AND book b.bookID has title b.bookName and costs $b.price
    AND review r.reviewID is by customer r.custID of book r.bookID with text r.review
    AND b.bookID = r.bookID
*/
SELECT b.bookID, r.reviewID
FROM Book b JOIN Reviews r ON b.bookID = r.bookID

我们经常希望INNER JOIN ON中的行加上右表列的NULL不匹配的左表行。这是LEFT JOIN ON。

...
FROM Book b LEFT JOIN Reviews r ON b.bookID = r.bookID
/*  the rows where
            book b.bookID has title b.bookName and costs $b.price
        AND review r.reviewID is by customer r.custID of book r.bookID with text r.review
        AND b.bookID = r.bookID
    OR      book b.bookID has title b.bookName and costs $b.price
        AND NOT EXISTS r.reviewID, r.custID, r.book, r.review [
                review r.reviewID is by customer r.custID of book r.bookID with text r.review
                AND b.bookID = r.bookID
            ]
        AND r.reviewID IS NULL AND r.custID IS NULL AND r.book IS NULL AND r.review IS NULL
/*

所以你想要:

SELECT b.bookID, r.reviewID
FROM Book b LEFT JOIN Reviews r ON b.bookID = r.reviewID

或者也许:

SELECT DISTINCT b.bookName, r.review
FROM Book b LEFT JOIN Reviews r ON b.bookID = r.reviewID

CROSS JOIN vs INNER JOIN in SQL Server 2008
Is there any rule of thumb to construct SQL query from a human-readable description?

当存在重复或NULL时,查询很复杂,因为它们的存在在AND,OR,NOT,FOR SOME等方面变得越来越模糊地与给定情况相关(它很容易生成谓词,但他们说的很复杂。)