2012-03-04 139 views
0

我有一個表,如:叫做書從兩個或多個變量的Mysql內部連接?

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

,我想一個VIEW從書本和作家:

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

,這樣我可以有我應該是這樣的表中查看低於,但應顯示而不是來自tabel AUTHOR的作者id作者姓名。

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

你守ld規範化你的數據庫,也就是說,有一個與book_id和author_ids匹配的表。你肯定會遇到單個列中有多個值的問題 – knittl 2012-03-04 11:44:30

回答

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 
+0

我有兩個作者,但問題是有時候超過20個作者,它是一個在線文章社區。 – Krueger 2012-03-04 12:03:44

+0

@drake,所以我希望你能理解答案的第二部分,並且如果沒有的話,請閱讀表'BOOK_AUTHOR',隨時提問。 – Vyktor 2012-03-04 12:48:40

+0

尼斯的詳細回覆,但BOOK_AUTHOR主鍵應該是(book_id,author_id),而不是具有多餘的代理鍵。 – nnichols 2012-03-04 18:16:41

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 

但是這將是一個非常緩慢的,醜陋的解決方案,即使它的工作原理。一個更好的解決辦法是在你的book表擺脫author列,而是添加一個鏈接表是這樣的:

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