Mysql внутреннее объединение из двух или более переменных? - PullRequest
0 голосов
/ 04 марта 2012

У меня есть таблица типа: называется BOOKS

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

И я хочу VIEW от BOOKS и АВТОРА:

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

Так что я могу иметь вид, который яДолжно быть что-то вроде таблицы, приведенной ниже, но вместо идентификатора автора должно быть указано имя автора из таблицы AUTHOR.

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

Ответы [ 2 ]

3 голосов
/ 04 марта 2012

Ваш дизайн базы данных неверен. books.author должно быть INT и содержать внешний ключ для author.id. Таблица author должна содержать name VARCHAR(255) (или два столбца, ссылающихся на author_name, я до сих пор не уверен, есть ли у вас два автора или вы разделили имя на 2 записи).

Так что правильный дизайн будет:

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 голосов
/ 04 марта 2012

Как отмечает 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, я нечувствую, что добавление дополнительных столбцов идентификаторов в простые таблицы ссылок является хорошей идеей . В этой таблице уже есть совершенно хороший естественный первичный ключ - ему не нужен суррогатный ключ.)

Тогда вы сможете создать свой вид намного проще и эффективнее:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...