mysql - 如何连接相互依赖的表

标签 mysql database-design rdbms

假设我正在制作一个图书借阅数据库。

drop table lend_current;
drop table lend_history;
drop table books;

create table books ( id int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT);

create table lend_history (
 id int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT, 
 book_id int(11) NOT NULL,
 lender_name VARCHAR(50) NOT NULL,
 CONSTRAINT FK_books FOREIGN KEY(book_id) REFERENCES books(id));

create table lend_current (
  lend_history_id int(11) PRIMARY KEY NOT NULL,
  CONSTRAINT FK_lendhistory FOREIGN KEY(lend_history_id) REFERENCES lend_history(id));

INSERT INTO books (id) VALUE(1);
INSERT INTO books (id) VALUE(2);

INSERT INTO lend_history (id, book_id, lender_name) VALUES(1, 1, "mike");
INSERT INTO lend_history (id, book_id, lender_name) VALUES(2, 2, "jane");
INSERT INTO lend_history (id, book_id, lender_name) VALUES(3, 2, "ola");  /* this will be current lender */

INSERT INTO lend_current (lend_history_id) VALUES(3);

SELECT books.id, lend_history.lender_name FROM books
LEFT JOIN lend_history on lend_history.book_id=books.id
LEFT JOIN lend_current on lend_current.lend_history_id=lend_history.id

我希望我的查询列出所有具有当前借出者姓名的书籍,但如果没有人借出这本书,它仍应列出名称字段为 NULL 的那本书。

此查询列出了 id (2) 的书两次。但我希望它只显示一次当前贷方的名称。

我尝试了内部连接、右连接但无法实现。我错过了什么?

在阅读 Could I make a column in a table only allows one 'true' value and all other rows should be 'false' 之前,我曾经在借阅历史中有“is_current”列我决定为更好的做法创建一个单独的表。

最佳答案

由于您对“is_current”列的处理,您不能在三个表之间进行直接连接。一种方法是使用 Derived Tables (子查询);在子查询中,您可以获得所有“当前”的借出历史记录项。现在简单地LEFT JOIN books 表的子查询结果:

SELECT b.id, dt.lender_name 
FROM books AS b 
LEFT JOIN 
( 
  SELECT lh.book_id, lh.lender_name
  FROM lend_current AS lc 
  JOIN lend_history AS lh ON lh.id = lc.lend_history_id
) AS dt ON dt.book_id = b.id

View on DB Fiddle

结果

| id  | lender_name |
| --- | ----------- |
| 1   |             |
| 2   | ola         |

旁注:与其创建第三个表lend_current,我宁愿坚持你原来的有两个表的模式,bookslend_history。现在要确定哪个历史记录行是当前的,我们可以有两种方法:

  1. 您原来的方法:在 lend_history 表中有 is_current 字段(如果是当前行,则为 1。
  2. 或者,我们可以在 books 表中有一个 current_history_id 字段存储当前历史记录行的 id。如果这本书当前没有被借出,它将是 NULL。这也可以利用外键约束。

关于mysql - 如何连接相互依赖的表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57007907/

相关文章:

database - 数据库管理系统 : Meaning of the following Relational Calculus Example:

php - Mysql,根据日期选择行

php - 字典数据库上的 "Did you mean"特征

sql - 选择子句 : Optional Columns?

没有 SQL 的 RDBMS

mysql - MySQL 中为什么要在 ORDER 子句之后放置 LIMIT 子句?

mysql - 使用 Doctrine 保存行时 Doctrine_Connection_Mysql_Exception

mysql - 数据库设计 : how to model a table?

php - InnoDB外键困难?

mysql - 跨多个表搜索