Извлечение записей из таблицы внуков - PullRequest
4 голосов
/ 26 февраля 2011

Мой вопрос связан с Rails, но даже общий ответ SQL был бы полезен.

Я имею дело с четырьмя таблицами: категориями, книгами, категориями-книгами и рецептами.Категория имеет и принадлежит многим книгам.У книг много рецептов.

Переведено в коде Rails У меня есть:

class Category < ActiveRecord::Base
  has_and_belongs_to_many :books
end

class Book < ActiveRecord::Base
  has_and_belongs_to_many :categories
  has_many :recipes
end

class Recipe < ActiveRecord::Base
  belongs_to :book
end

Я пытаюсь получить все рецепты, содержащиеся в книгах, принадлежащих к данной категории.

Я знаю, как это сделать со многими запросами, но не с одним запросом.Со многими запросами я бы сделал:

recipes = []    
books = @category.books
books.each do |book|
  recipes << book.recipes.flatten
end

Мне это не нравится, потому что это требует N + 1 запросов.Возможно, мне нужно объединение, чтобы сделать все это сразу, но я не уверен насчет синтаксиса в ActiveRecord или SQL.Я использую MySQL.

Ответы [ 2 ]

1 голос
/ 26 февраля 2011

Не могу помочь с Рубином.Общий ответ SQL (с некоторыми предположениями относительно имен столбцов) будет выглядеть так:

SELECT Recipe.*
FROM Recipe
INNER JOIN Book ON Recipe.Book = Book.Id
INNER JOIN Category ON Book.Category = Category.Id
WHERE Category.Id = ?

EDIT Добавлена ​​другая версия запроса, чтобы соответствовать новой информации Пинки Брейна о таблицах и столбцах.Как то так?

SELECT Recipe.*
FROM Recipe
INNER JOIN Categories_Books ON Categories_Books.book_id = Recipe.book_id
WHERE Categories_Books.category_id = ?
0 голосов
/ 27 февраля 2011

Предполагая следующую структуру таблицы ...

category(
   category_id primary key
)

book(
   book_id primary key
)

recipes(
   recipe_id
  ,book_id
  ,primary key(recipe_id)  
)

categories_books(
   category_id
  ,book_id
  ,primary key(category_id, book_id)
)

... вы можете получить то, что хотите, с помощью следующего запроса, который возвращает все рецепты из всех книг в указанной категории.

select ...
  from categories_books c
  join book             b using(book_id)
  join recipes          r using(book_id)
 where c.category_id = ?;

Обратите внимание, что вы можете отбросить объединение до book, если вам не нужны никакие данные из таблицы, поскольку вы можете присоединиться напрямую с categories_books до recipes через book_id. Кроме того, убедитесь, что есть (неуникальный) индекс для recipes.book_id

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...