Mysql内连接来自两个或多个变量?

时间:2012-03-04 11:39:09

标签: mysql inner-join

我有一张名为:BOOKS

的表格
+------+-------------------+---------------+
| id   |  book_title       |  author       |
+------+-------------------+---------------+
| 1    |  learning mysql   |  1234 12      |
+------+-------------------+---------------+
| 2    |  learning php     |  125 50       |
+------+-------------------+---------------+

我想要一个来自BOOKS和AUTHOR的VIEW

+------+-------------------+  
| id   |  author           |
+------+-------------------+
| 12   |  JOHN             |
+------+-------------------+
| 50   |  PAUL             |
+------+-------------------+
| 125  |  CHRISTOPHER      |
+------+-------------------+
| 1234 |  PATRICK          |
+------+-------------------+

所以我可以有一个VIEW,我应该像下面的表格,但应该显示而不是作者ID作者姓名来自tabel AUTHOR。

+------+-------------------+-----------------------------------+
| id   |  book_title       |  author                           |
+------+-------------------+-----------------------------------+
| 1    |  learning mysql   |  PATRICK                          |
+------+-------------------+-----------------------------------+
| 1    |  learning mysql   |  CHRISTOPHER                      |
+------+-------------------+-----------------------------------+
| 2    |  learning php     |  JOHN                             |
+------+-------------------+-----------------------------------+
| 2    |  learning php     |  PAUL                             |
+------+-------------------+-----------------------------------+

2 个答案:

答案 0 :(得分:3)

您的数据库设计错误。 books.author应为INT并包含author.id的外键。表格author应该包含name VARCHAR(255)(或两个引用author_name的列,我仍然不确定您是否有两位作者,或者您将名称分为两个条目)。

所以正确的设计是:

BOOKS (
  id INT,
  book_title VARCHAR(255),
  author INT, -- only if each book has just one author
  PRIMARY KEY (id)
)

AUTHOR (
  id INT,
  name VARCHAR(255),
  first_name_id INT, -- If you want to split names into more columns
  PRIMARY KEY (id)
)

-- If you need more authors for one book
-- you maybe should keep original (primary) author id
BOOK_AUTHOR (
  book_id INT,
  author_id INT,
  PRIMARY KEY (book_id, author_id)
);

您可以选择以下数据:

SELECT BOOKS.id, BOOKS.book_title, AUTHOR.name AS author
FROM BOOKS
-- Study difference between left and inner joins
INNER JOIN AUTHOR on AUTHOR.id = BOOKS.author

如果你需要为一本书增加作者:

SELECT BOOKS.id, BOOKS.book_title, AUTHOR.name AS author
FROM BOOKS
LEFT JOIN BOOK_AUTHOR on BOOK_AUTHOR.book_id = BOOKS.id
LEFT JOIN AUTHOR on AUTHOR.id = BOOK_AUTHOR.author_id

您可能需要将作者输出为Wolfgang Goethe; Oscar Wilde,而不是使用GROUP_CONCAT

SELECT BOOKS.id, BOOKS.book_title,
       GROUP_CONCAT( AUTHOR.name SEPARATOR '; ') AS author
FROM BOOKS
LEFT JOIN BOOK_AUTHOR on BOOK_AUTHOR.book_id = BOOKS.id
LEFT JOIN AUTHOR on AUTHOR.id = BOOK_AUTHOR.author_id
GROUP BY BOOKS.id

答案 1 :(得分:0)

正如knittl在评论中指出的那样,你绝对应该修复你的数据库设计。也就是说,这是使用现有架构的“暴力和无知”解决方案:

CREATE VIEW book_author (id, book_title, author)
AS SELECT book.id, book.book_title, author.author
FROM book
  JOIN author ON FIND_IN_SET(author.id, REPLACE(book.author, ' ', ',')) > 0

但这将是一个非常缓慢和丑陋的解决方案,即使它有效。更好的解决方案是删除author表中的book列,而是添加如下链接表:

CREATE TABLE book_author (
  book INTEGER NOT NULL,
  author INTEGER NOT NULL,
  PRIMARY KEY (book, author),
  UNIQUE KEY (author, book)   /* for "all books by author X" queries */
)

(与Vyktor不同,I don't feel that adding extra ID columns to simple link tables is a good idea。该表中已经有一个非常好的自然主键 - 它不需要需要一个代理键。)

然后,您可以更加轻松有效地创建视图:

CREATE VIEW book_author (id, book_title, author)
AS SELECT book.id, book.book_title, author.author
FROM book
  JOIN book_author ON book_author.book = book.id
  JOIN author ON book_author.author = author.id