MySQL - 请帮助修复查询中的错误[重复]
Posted
技术标签:
【中文标题】MySQL - 请帮助修复查询中的错误[重复]【英文标题】:MySQL - please help fix a mistake in the query [duplicate] 【发布时间】:2020-01-17 07:23:16 【问题描述】:我有三个表,多对多关系:
书籍
CREATE TABLE `books` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`title` VARCHAR(100) NOT NULL,
`condition` ENUM('mint', 'new', 'medium', 'poor', 'needs replacement'),
`date_added` DATE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
作者
CREATE TABLE `authors` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(50) NOT NULL,
`pseudonim` VARCHAR(50) NOT NULL,
`year_of_birth` INT(4) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
AUTHORS_BOOKS 表:
CREATE TABLE `authors_books` (
`author_id` INT(11) UNSIGNED NOT NULL,
`book_id` INT(11) UNSIGNED NOT NULL,
PRIMARY KEY (`author_id`, `book_id`),
CONSTRAINT `fk1_authors_authors_id` FOREIGN KEY (`author_id`) REFERENCES `authors` (`id`)
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `fk2_books_book_id` FOREIGN KEY (`book_id`) REFERENCES `books` (`id`)
ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
我要做的是获取包含以下信息的数据:
-
图书编号
书名,
作者姓名
我的查询没有返回相关数据,我可能在某处错过了正确的连接,但正如我所见,最大的问题在于我的理解。如果有人可以检查我所看到的事情的后果,我将不胜感激:
-
在我的视图中指定我需要的确切列:
SELECT b.id, b.title, a.name FROM books as b
-
加入 book_id 上的数据透视表:
INNER JOIN authors_books as ab on b.id = ab.book_id
-
因为我需要作者的姓名,所以我要再加入一次以将作者表带入游戏:
INNER JOIN authors AS a ON ab.authors_id = a.id
所以最后我有以下查询
SELECT b.id, b.title, a.name FROM books as b
INNER JOIN authors_books as ab on b.id = ab.book_id
INNER JOIN authors AS a ON ab.authors_id = a.id
这会返回一个不完整的书籍列表,其中大部分都跳过了。我不明白它是怎么发生的。我在哪里犯了错误,我错过了什么概念?
【问题讨论】:
我认为查询没有任何问题。您能否向我们展示一些示例数据,您得到的结果以及您期望的结果。 是的 - 需要查看示例数据。 您的代码看起来不错,您可以通过一次查询获得预期结果吗?你能给我们看看样品吗? 您的代码是正确的,问题来自您的数据,它只会返回找到作者的书籍(使用 authors_books 数据透视表)。解决此问题的一种方法是使用左连接(在找不到作者时返回a.name = null
)。此外,如果图书可以有多个作者(您的表格允许),那么该图书将在您的搜索结果中出现多次。
很高兴有人有时不了解我 :D 祝你工作顺利。
【参考方案1】:
试试
SELECT b.id, b.title, a.name FROM books as b
LEFT OUTER JOIN authors_books as ab on b.id = ab.book_id
LEFT OUTER JOIN authors AS a ON ab.authors_id = a.i
因为您缺少一些行,所以我认为您应该使用左外连接,这样您就可以获得针对主表书籍的完整结果
【讨论】:
这里不需要外连接。虽然确实,我应该将第二个 JOIN 语句更改为 LEFT 我了解,但查询是否提取了您之前提到的所有缺失行?如果是这样,我建议您稍微更改一下此查询,例如添加 where ab.book_id is not null。【参考方案2】:正如@BUcorp 所述,主要问题来自缺少行。
要解决这个问题,您可以使用LEFT JOIN
而不是INNER JOIN
来确保所有书籍都出现在您的结果中,即使它们没有作者或未知作者(例如,@ 中不存在 ID) 987654323@):
SELECT b.id, b.title, a.name FROM books as b
LEFT JOIN authors_books as ab on b.id = ab.book_id
LEFT JOIN authors AS a ON ab.authors_id = a.i
最后,为了避免在一本书有多个作者的情况下获得多个条目(如果这可能发生在您的情况下),您可以例如使用GROUP_CONCAT(a.name) AS authors
和GROUP BY b.id
【讨论】:
哈哈哈谢谢提及以上是关于MySQL - 请帮助修复查询中的错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章
我的查询显示 heidisql 错误,不知道如何修复 [重复]