在同一个 table 中加入两个外键引用同一个主键
Joining two foregin keys in the same table references the same primary key
我正在尝试加入多个 tables(BooksReview
, Followers
, Books
) 与 Users
table 其中Books
引用了 userId
来自 Users
,BooksReview
引用了 userId
,userId
评论了一本书并引用了 bookId
来自 Books
这是被审查的书 ID,最后但并非最不重要的是 Followers
table(我认为这里是问题所在)有两个来自相同主键的引用它有 follower
来自 userId
in Users
table 和 followed
也来自 userId
in Users
table.
问题:我创建了一个 MySQL 查询来获取基于特定用户的特定图书的书评数量,并获取该用户的图书数量和关注者数量 he/she 有,但是当我将 Followers
连接部分添加到我的查询时,它显示所有值的结果为 0,预期值为 4 本书、4 条评论和 1 个关注者。
我试图更改查询中的连接类型,但结果相同,并搜索了在同一 table 中连接两个外键以获得相同的主键,但我没有找到任何有用的东西.
```
CREATE TABLE IF NOT EXISTS `Authors`.`Users` (
`userId` VARCHAR(100) NOT NULL,
`username` VARCHAR(25) NOT NULL,
`password` VARCHAR(16) NOT NULL,
`email` VARCHAR(254) NOT NULL,
`birthday` DATE NULL,
`aboutMe` TEXT(300) NOT NULL,
`facebookAccount` VARCHAR(25) NULL,
`twitterAccount` VARCHAR(25) NULL,
`linkedinAccount` VARCHAR(25) NULL,
`profileImage` VARCHAR(200) NULL,
PRIMARY KEY (`userId`),
UNIQUE INDEX `username_UNIQUE` (`username` ASC),
UNIQUE INDEX `email_UNIQUE` (`email` ASC))
ENGINE = InnoDB;
```
CREATE TABLE IF NOT EXISTS `Authors`.`Books` (
`bookId` VARCHAR(100) NOT NULL,
`bookCategory` VARCHAR(25) NOT NULL,
`title` VARCHAR(25) NOT NULL,
`bookCover` VARCHAR(45) NOT NULL,
`bookDescription` VARCHAR(200) NOT NULL,
`userId` VARCHAR(100) NOT NULL,
`price` DECIMAL(2,2) NOT NULL,
`introduction` VARCHAR(300) NOT NULL,
PRIMARY KEY (`bookId`),
INDEX `userId_idx` (`userId` ASC),
CONSTRAINT `userId`
FOREIGN KEY (`userId`)
REFERENCES `Authors`.`Users` (`userId`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
```
```
CREATE TABLE IF NOT EXISTS `Authors`.`BooksReview` (
`bookId` VARCHAR(100) NOT NULL,
`rateMessage` VARCHAR(100) NULL,
`rateNumber` DECIMAL(1,1) NULL,
`userId` VARCHAR(100) NOT NULL,
INDEX `userId_idx` (`userId` ASC),
CONSTRAINT `bookId`
FOREIGN KEY (`bookId`)
REFERENCES `Authors`.`Books` (`bookId`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `userId`
FOREIGN KEY (`userId`)
REFERENCES `Authors`.`Users` (`userId`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
```
CREATE TABLE IF NOT EXISTS `Authors`.`Followers` (
`follower` VARCHAR(100) NOT NULL,
`followed` VARCHAR(100) NOT NULL,
INDEX `follower_idx` (`follower` ASC),
INDEX `followed_idx` (`followed` ASC),
CONSTRAINT `follower`
FOREIGN KEY (`follower`)
REFERENCES `Authors`.`Users` (`userId`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `followed`
FOREIGN KEY (`followed`)
REFERENCES `Authors`.`Users` (`userId`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
THIS IS THE QUERY
SELECT count(br.bookId) AS reviewsCount, count(b.bookId) AS booksCount, count(f.follower) AS followersCount
FROM Users AS u
LEFT JOIN Books AS b ON b.userId = u.userId
JOIN Followers AS f ON b.userId = f.followed AND f.follower = u.userId
INNER JOIN BooksReview AS br ON br.bookId = b.bookId
AND b.bookId IN (SELECT bookId
FROM Books
WHERE userId = 'dbb21849-ccce-4af1-aa0f-6653919bf956');
我预计结果应该是 1 个关注者、4 本书和 4 条评论
但实际结果全部为0。
DML:
Users
->
userId: dbb21849-ccce-4af1-aa0f-6653919bf956
username: mostafabbbaron
等...
Books
->
userId: dbb21849-ccce-4af1-aa0f-6653919bf956
bookId: 5f39c1ae-5e99-4b3a-8ee0-97a80c1ba9b1
等...
Followers
->
follower: dbb21849-ccce-4af1-aa0f-6653919bf956
folllowed: b39c8e0c-4124-4339-8c30-e1fc8db5f2d4
等...
BooksReviews
->
userId: dbb21849-ccce-4af1-aa0f-6653919bf956
bookId: aa44a455-dc28-476f-b4b9-47563a717f03
等...
无论哪种方式,您的查询都是错误的。但是结果为零的原因可能是这些条件:b.userId = u.userId
和 b.userId = f.followed AND f.follower = u.userId
.
如果 b.userId = u.userId
和 b.userId = f.followed
那么 f.followed = u.userId
如果 f.followed = u.userId
和 f.follower = u.userId
那么 f.followed = f.follower
这意味着用户必须遵循 himself/herself,我怀疑是这样。
我将按以下方式编写查询:
SELECT
count(DISTINCT b.bookId) AS booksCount,
count(br.bookId) AS reviewsCount,
(SELECT COUNT(*) FROM Followers AS f WHERE f.followed = u.userId) AS followersCount
FROM Users AS u
LEFT JOIN Books AS b ON b.userId = u.userId
LEFT JOIN BooksReview AS br ON br.bookId = b.bookId
WHERE u.userId = 'dbb21849-ccce-4af1-aa0f-6653919bf956'
注意:虽然 Users LEFT JOIN Books LEFT JOIN BooksReview
很好,因为您有 "relation chain" Users <- Books <- BooksReview
。但是你不应该只是加入 Followers
table,因为它与 Books
或 BooksReview
并没有真正的关系,也不适合那个链。这就是为什么我在 SELECT 子句中使用子查询来计算关注者的原因。
我正在尝试加入多个 tables(BooksReview
, Followers
, Books
) 与 Users
table 其中Books
引用了 userId
来自 Users
,BooksReview
引用了 userId
,userId
评论了一本书并引用了 bookId
来自 Books
这是被审查的书 ID,最后但并非最不重要的是 Followers
table(我认为这里是问题所在)有两个来自相同主键的引用它有 follower
来自 userId
in Users
table 和 followed
也来自 userId
in Users
table.
问题:我创建了一个 MySQL 查询来获取基于特定用户的特定图书的书评数量,并获取该用户的图书数量和关注者数量 he/she 有,但是当我将 Followers
连接部分添加到我的查询时,它显示所有值的结果为 0,预期值为 4 本书、4 条评论和 1 个关注者。
我试图更改查询中的连接类型,但结果相同,并搜索了在同一 table 中连接两个外键以获得相同的主键,但我没有找到任何有用的东西.
```
CREATE TABLE IF NOT EXISTS `Authors`.`Users` (
`userId` VARCHAR(100) NOT NULL,
`username` VARCHAR(25) NOT NULL,
`password` VARCHAR(16) NOT NULL,
`email` VARCHAR(254) NOT NULL,
`birthday` DATE NULL,
`aboutMe` TEXT(300) NOT NULL,
`facebookAccount` VARCHAR(25) NULL,
`twitterAccount` VARCHAR(25) NULL,
`linkedinAccount` VARCHAR(25) NULL,
`profileImage` VARCHAR(200) NULL,
PRIMARY KEY (`userId`),
UNIQUE INDEX `username_UNIQUE` (`username` ASC),
UNIQUE INDEX `email_UNIQUE` (`email` ASC))
ENGINE = InnoDB;
```
CREATE TABLE IF NOT EXISTS `Authors`.`Books` (
`bookId` VARCHAR(100) NOT NULL,
`bookCategory` VARCHAR(25) NOT NULL,
`title` VARCHAR(25) NOT NULL,
`bookCover` VARCHAR(45) NOT NULL,
`bookDescription` VARCHAR(200) NOT NULL,
`userId` VARCHAR(100) NOT NULL,
`price` DECIMAL(2,2) NOT NULL,
`introduction` VARCHAR(300) NOT NULL,
PRIMARY KEY (`bookId`),
INDEX `userId_idx` (`userId` ASC),
CONSTRAINT `userId`
FOREIGN KEY (`userId`)
REFERENCES `Authors`.`Users` (`userId`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
```
```
CREATE TABLE IF NOT EXISTS `Authors`.`BooksReview` (
`bookId` VARCHAR(100) NOT NULL,
`rateMessage` VARCHAR(100) NULL,
`rateNumber` DECIMAL(1,1) NULL,
`userId` VARCHAR(100) NOT NULL,
INDEX `userId_idx` (`userId` ASC),
CONSTRAINT `bookId`
FOREIGN KEY (`bookId`)
REFERENCES `Authors`.`Books` (`bookId`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `userId`
FOREIGN KEY (`userId`)
REFERENCES `Authors`.`Users` (`userId`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
```
CREATE TABLE IF NOT EXISTS `Authors`.`Followers` (
`follower` VARCHAR(100) NOT NULL,
`followed` VARCHAR(100) NOT NULL,
INDEX `follower_idx` (`follower` ASC),
INDEX `followed_idx` (`followed` ASC),
CONSTRAINT `follower`
FOREIGN KEY (`follower`)
REFERENCES `Authors`.`Users` (`userId`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `followed`
FOREIGN KEY (`followed`)
REFERENCES `Authors`.`Users` (`userId`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
THIS IS THE QUERY
SELECT count(br.bookId) AS reviewsCount, count(b.bookId) AS booksCount, count(f.follower) AS followersCount
FROM Users AS u
LEFT JOIN Books AS b ON b.userId = u.userId
JOIN Followers AS f ON b.userId = f.followed AND f.follower = u.userId
INNER JOIN BooksReview AS br ON br.bookId = b.bookId
AND b.bookId IN (SELECT bookId
FROM Books
WHERE userId = 'dbb21849-ccce-4af1-aa0f-6653919bf956');
我预计结果应该是 1 个关注者、4 本书和 4 条评论 但实际结果全部为0。
DML:
Users
->
userId: dbb21849-ccce-4af1-aa0f-6653919bf956
username: mostafabbbaron
等...
Books
->
userId: dbb21849-ccce-4af1-aa0f-6653919bf956
bookId: 5f39c1ae-5e99-4b3a-8ee0-97a80c1ba9b1
等...
Followers
->
follower: dbb21849-ccce-4af1-aa0f-6653919bf956
folllowed: b39c8e0c-4124-4339-8c30-e1fc8db5f2d4
等...
BooksReviews
->
userId: dbb21849-ccce-4af1-aa0f-6653919bf956
bookId: aa44a455-dc28-476f-b4b9-47563a717f03
等...
无论哪种方式,您的查询都是错误的。但是结果为零的原因可能是这些条件:b.userId = u.userId
和 b.userId = f.followed AND f.follower = u.userId
.
如果 b.userId = u.userId
和 b.userId = f.followed
那么 f.followed = u.userId
如果 f.followed = u.userId
和 f.follower = u.userId
那么 f.followed = f.follower
这意味着用户必须遵循 himself/herself,我怀疑是这样。
我将按以下方式编写查询:
SELECT
count(DISTINCT b.bookId) AS booksCount,
count(br.bookId) AS reviewsCount,
(SELECT COUNT(*) FROM Followers AS f WHERE f.followed = u.userId) AS followersCount
FROM Users AS u
LEFT JOIN Books AS b ON b.userId = u.userId
LEFT JOIN BooksReview AS br ON br.bookId = b.bookId
WHERE u.userId = 'dbb21849-ccce-4af1-aa0f-6653919bf956'
注意:虽然 Users LEFT JOIN Books LEFT JOIN BooksReview
很好,因为您有 "relation chain" Users <- Books <- BooksReview
。但是你不应该只是加入 Followers
table,因为它与 Books
或 BooksReview
并没有真正的关系,也不适合那个链。这就是为什么我在 SELECT 子句中使用子查询来计算关注者的原因。