mysql - 如何选择读过 Steven King 而未读过 William Shakespeare 的用户

标签 mysql

在研究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/

相关文章:

mysql - 如何在特定时间执行 mysql 事件而不使用 if

mysql - 如何从大表的子集中选择mysql中的n个随机行?

php - 函数准备查询

php - laravel eloquent where like 整数运算符

php - 在表单/电子邮件中复制/粘贴后出现奇怪的字符

python - 创建表时Django MySQL错误

php - 优化大量 MySQL INSERT

php - Sphinx 实时索引 UPDATE 语句不影响所有行

mysql - 无法在 Windows 7 机器上将 MySql 作为服务启动

mysql - 根据字段的组合权重对结果进行排序