Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 创建一个表格,给我一个有评论和没有评论的书籍列表_Sql_Sql Server_Join_Foreign Keys_Left Join - Fatal编程技术网

Sql 创建一个表格,给我一个有评论和没有评论的书籍列表

Sql 创建一个表格,给我一个有评论和没有评论的书籍列表,sql,sql-server,join,foreign-keys,left-join,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 (

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

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)
)
对于我的任务,我被赋予以下任务:

编写一个查询,显示所有书籍的列表,对于有评论的书籍,列出评论


我完全糊涂了,不知道该如何开始处理这个问题。我不知道我可以使用任何连接组合。我对SQL相当陌生。让我大吃一惊的是,我必须访问这两个表,使用图书id检索这两个图书名称,然后创建与相应评论的关联。同时也列出了没有评论的书籍。

LEFT JOIN关键字返回左表(表1)中的所有记录,以及右表(表2)中匹配的记录。如果没有匹配项,则结果从右侧为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

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

我将如何做到这一点,加入关于书籍匹配的评论:

SELECT Books.*, Reviews.review
FROM Books, Reviews
LEFT JOIN Book.bookID ON Reviews.bookID
如果您不想要没有评论的,可以使用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

按照Sean Lange的说法,通过使用内部连接跳过WHERE子句来简化查询

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

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

SELECT bookName,
       review
  FROM book
  LEFT JOIN reviews
    ON book.bookID = reviews.bookID
编写一个查询,显示所有书籍的列表,对于有评论的书籍,列出评论

你引用的问题陈述不清楚。首先,它打算但不表示“显示(bookID,reviewID)行列表,其中…”。第二,它的意图是,但并没有表达这样的意思:“……这本书在哪里有评论,或者这本书没有评论,而被评论者是……”什么?你应该知道/猜测/决定用。。。“空”?空字符串?谁知道呢,还不清楚

或者他们可能想要“(bookName,review)行,其中具有该名称的某本书有一些评论,其中文本是(列)review,或者没有评论,而(列)review是…”。(请注意,这是“一些”,而不是“那个”。)谁知道,这还不清楚

(这种草率渗透到数据库教育学和文化中。)

让我大吃一惊的是,我必须访问这两个表,使用图书id检索这两个图书名称,然后创建与相应评论的关联

这就是JOINs所做的

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

/*  the rows where
    book bookID has title bookName and costs $price
*/
select * from Book
在FROM中,每个参数表列都被重命名为以其表名/别名和一个点作为前缀。然后,内部联接从每一行生成每一行的组合。当没有重复项时,内部联接将保存根据连接/和参数关联而关联的行。ON和WHERE都修改FROM结果以返回通过连接/和条件关联的行

...
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
*/
选择“在删除点前缀时添加和删除列”。当我们不想要复制品,但可能得到一些时,我们使用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
我们经常希望来自内部联接的行加上不匹配的左表行对右表列扩展NULL。那是左上角

...
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


当存在重复项或空项时,查询会变得复杂,因为它们的存在与给定情况在and、or、NOT等方面的关系越来越模糊(生成谓词很简单,但它们所说的内容很复杂。)

您有一个带有BookID的“books”表和一个带有BookID的“reviews”表。您是否不理解联接的概念,或者是否有其他东西让您感到困惑?您可能应该花一点时间来理解联接@YellowBedder对不起,我错过了一堂课,一直想赶上来XD@SeanLange维恩图说明了内部连接与外部连接以及相交与并集与除外。它们没有说明JOIN是如何工作的。(例如,在你的链接中,博客作者在评论中否定了他们的博客。)在你提问之前,至少阅读一下谷歌的许多热门文章,以及你问题的清晰、简洁和具体的版本。在这里,任何SQLIntro的第一页都会把你带到某个地方,你可以把它放到你的帖子中&这会影响你的问题。你的语法是无效的。不能有这样的隐式交叉联接和左联接。不知道你为什么认为你需要第二部分的cte?在这里,左连接就足够了。@SeanLange哎呀,我只是从中取出评论吗?@SeanLange我没有机会测试它,但我认为左连接将在ID匹配的地方显示空值?这是正确的。但你不需要cte。你只需要一个where子句,这样看起来更好。但是,如果您只想要那些有审查的,您可以使用内部联接并跳过where子句。:)
SELECT DISTINCT b.bookName, r.review
FROM Book b LEFT JOIN Reviews r ON b.bookID = r.reviewID