在研究mysql项目时,我未能将JOIN的知识应用到实际情况中,查询本身的逻辑存在问题。
我的目标是进行一个需要 6 个表进行交互的查询。
第一个连接表批处理:
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;
通过旋转表连接多对多
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;
第二批如屏幕截图所示 - 书籍、用户和 user_orders: https://paste.pics/30d57ef8c6f5adfab23ce1158fb30f09
我正在尝试的是让所有读过 King 而没有读过莎士比亚的用户。
我是这样看的:
- 寻址用户表,因为我需要一个用户:
SELECT * FROM users
我需要通过书籍进行搜索,所以
LEFT JOIN user_orders ON users.id = user_orders.user_id LEFT JOIN books ON user_orders.book_id = books.id
按照这个逻辑,我最终链接了功能失调的 JOINS,我错过了什么?这个逻辑应该如何构建?
最佳答案
我认为您不需要Left Joins
,但您可能需要一个NOT EXISTS
,下面的查询应该可以做到:
SELECT u.* FROM users u
INNER JOIN user_orders uo ON u.id=uo.user_id
INNER JOIN books b ON uo.book_id=b.id
INNER JOIN authors_books ab ON ab.book_id = b.id
INNER JOIN authors a ON ab.author_id=a.id
WHERE a.name = 'Steven King'
AND NOT EXISTS (
SELECT 1 FROM users u2
INNER JOIN user_orders uo2 ON u2.id=uo2.user_id AND uo2.user_id = uo.user_id
INNER JOIN books b2 ON uo2.book_id=b2.id
INNER JOIN authors_books ab2 ON ab2.book_id = b2.id
INNER JOIN authors a2 ON ab2.author_id=a2.id
WHERE a2.name = 'Shakespear')
没有示例数据,我无法对此进行测试。它可能可以简化,因为它目前看起来有点难看,但它应该给你一个起点。
关于mysql - 如何选择读过 Steven King 而未读过 William Shakespeare 的用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57587217/