Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Выборка из трех таблиц
 
 автор: levsha   (01.02.2011 в 16:02)   письмо автору
 
 

Добрый день. с sql у меня плохо, поэтому решил обратиться за помощью. Помогите пожалуйста.

У меня есть 3 таблицы:
Таблица книг - books
Поля: id, name

Таблица авторов - authors
Поля: id, fio

Перекрестная таблица - book_authors, в которой два поля:
idBook - id книги,
idAuthor - id автора.
То есть в ней храниться сколько у каждой книг авторов и сколько у каждого автора книг.

Задача.
Как мне, при формирование списка книг сразу же выбирать всех авторов данной книги.
То есть, чтобы в результате запроса было поле Authors в котором все ФИО авторов данной книги через запятую.

Заранее спасибо.

  Ответить  
 
 автор: cheops   (01.02.2011 в 17:49)   письмо автору
 
   для: levsha   (01.02.2011 в 16:02)
 

Можно поступить следующим образом
SELECT b.name AS name,
GROUP_CONCAT(a.fio ORDER BY a.fio SEPARATOR ', ') AS authors
FROM books AS b LEFT JOIN book_authors ba ON (b.id = ba.idBook)
LEFT JOIN authors AS a ON (a.id = ba.idAuthor)
GROUP BY b.name

PS Сдается мне в таблицу book_authors нужно ввести еще одно поле для задания порядка авторов, чтобы его можно было использовать в конструкции ORDER BY, при объединении полей при помощи GROUP_CONCAT().

  Ответить  
 
 автор: levsha   (01.02.2011 в 17:57)   письмо автору
 
   для: cheops   (01.02.2011 в 17:49)
 

Спасибо! Порядок авторов не так важен, пускай будет пока по алфавиту, то есть по fio, но ваше предложение возьму на заметку.

  Ответить  
 
 автор: levsha   (01.02.2011 в 17:58)   письмо автору
 
   для: cheops   (01.02.2011 в 17:49)
 

Вы могли бы посоветовать книгу по составлению сложных запросов и проектированию БД?

  Ответить  
 
 автор: cheops   (01.02.2011 в 18:07)   письмо автору
 
   для: levsha   (01.02.2011 в 17:58)
 

Для начала пойдет любая книга по SQL (правда чистых книг не так много, в большинстве случаев идет привязка к конкретной реализации). Можно посмотреть наши книги, посвященные MySQL (правда некоторые новые конструкции в них не описываются и их можно найти только в мануале и только на английском языке - руки не доходят выпустить новые издания книг).

  Ответить  
 
 автор: levsha   (01.02.2011 в 19:55)   письмо автору
 
   для: cheops   (01.02.2011 в 18:07)
 

Да в том то и дело, что я читал книги по sql, в основном теория, но там все достаточно простые бд описывались. Хотелось бы почитать книги где описывалось проектирование сложных бд и многотабличных запросов, с большой практикой. желательно конечно чтобы это было связано с mysql

  Ответить  
 
 автор: cheops   (01.02.2011 в 20:06)   письмо автору
 
   для: levsha   (01.02.2011 в 19:55)
 

Есть парочка книг, с которыми стоило бы ознакомиться, правда, в книгах представлена далеко не современная точка зрения на SQL. Правда, это классика, т.е. если вы её проработаете - вам SQL будет поколено, никакие сложные запросы вас не испугают, а чтение мануала упростится на порядки.
SQL для профессионалов. Программирование
SQL
SQL

  Ответить  
 
 автор: levsha   (02.02.2011 в 13:21)   письмо автору
 
   для: levsha   (01.02.2011 в 16:02)
 

А вот смотрите, у меня в таблице с книгами есть поле - тип книги - type, то есть структура такая:
Поля: id, name, type. Тип, то есть учебное пособие, монография, числовой тип int(1).

Тип все время стандартный, может принимать значение от 1 до 5.

Как мне выбрать авторов и подсчитать их кол-во различного типа книг, чтобы результат также был в одной таблице, чтоб там были колонки countTypeMonography (это когда тип равен 1), countTypeStuBook (учебное пособие, тип 2). Примерно вот так

  Ответить  
 
 автор: cheops   (02.02.2011 в 14:04)   письмо автору
 
   для: levsha   (02.02.2011 в 13:21)
 

Хм... Это обязательно должен быть один запрос? Если вложенны запросы не помещать в FROM, то можно поступить так
SELECT a.fio, COUNT(b.type) AS countTypeMonography
FROM authors AS a LEFT JOIN book_authors ba ON (a.id = ba.idAuthor)
LEFT JOIN books AS b ON (b.id = ba.idBook)
WHERE b.type = 1
GROUP BY a.id
ORDER BY a.fio

Но это таблица только с одним типом книг, такой запрос придется выполнять для каждого из типа.

  Ответить  
 
 автор: levsha   (02.02.2011 в 19:07)   письмо автору
 
   для: cheops   (02.02.2011 в 14:04)
 

Спасибо большое, что помогаете мне. Я тут подумал, что правильнее будет сделать вот так.
Привожу только необходимые поля.
Итак, у меня 3 таблицы.
Таблица материалов - materials
Поля: id, name, type (тип может принимать значения: 0 - текст, 1 - аудио, 2 - видео, 3 - программа)

Таблица авторов - authors
Поля: id, fio

Перекрестная таблица - materials_authors, в которой два поля:
idMaterial - id материала,
idAuthor - id автора.
То есть в ней храниться сколько у каждого материала авторов и сколько у каждого автора материалов.

Итак, мне нужно составить запросы.
1. Вывод всех материалов с полем авторы, в котором объединены все авторы материала. За это спасибо!
2. Получить список материалов по выбранному автору (по id автора).
3. Получить список материалов по выбранному автору и заданному типу материала. (по id автора и типу материала type)
4. Получить инфу об авторе и кол-ве каждого типа материала (по id автора). В результате запроса будут 4 дополнительных столбца countText, countAudio, countVideo, countProg к инф. об авторе

Вот, подскажите пожалуйста!

  Ответить  
 
 автор: levsha   (02.02.2011 в 19:20)   письмо автору
 
   для: levsha   (02.02.2011 в 19:07)
 

То есть для 2-го запроса:

SELECT  m.name, GROUP_CONCAT(a.fio) fios 
FROM materials m
LEFT JOIN materials_authors ma ON m.id = ma.idMaterial
LEFT JOIN authors a ON a.id = ma.idAuthor
WHERE a.id = {ID АВТОРА}
GROUP BY m.id


Для 3-го запроса

SELECT  m.name, GROUP_CONCAT(a.fio) fios 
FROM materials m
LEFT JOIN materials_authors ma ON m.id = ma.idMaterial
LEFT JOIN authors a ON a.id = ma.idAuthor
WHERE a.id = {ID АВТОРА} AND m.type = {ТИП МАТЕРИАЛА}
GROUP BY m.id


Так?

  Ответить  
 
 автор: cheops   (03.02.2011 в 10:56)   письмо автору
 
   для: levsha   (02.02.2011 в 19:20)
 

Если работает, то так :)

  Ответить  
 
 автор: levsha   (03.02.2011 в 12:55)   письмо автору
 
   для: cheops   (03.02.2011 в 10:56)
 

я еще не проверял, просто спросить хотел, правильно ли я составил)

  Ответить  
 
 автор: cheops   (03.02.2011 в 13:30)   письмо автору
 
   для: levsha   (03.02.2011 в 12:55)
 

Ну, на первый взляд никаких ошибок не видно, нужно попробовать запросы (это лучше вам сделать - у вас база данных более полная - у меня лишь набросок с парой тестовых записей).

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования