Извлечение строк из третьей таблицы, которые соответствуют двум сводным таблицам - PullRequest
0 голосов
/ 16 мая 2018

В моем приложении Laravel есть 5 таблиц. 3 основных таблицы: books, places и tags. Таблица books имеет сводную таблицу, чтобы связать ее с тегами: book_tags. Таблица places также имеет сводную таблицу: place_tags. Теперь для каждого места я хотел бы получить книги, основанные на тегах, которые находятся в place_tags и book_tags.

books
    book_tags
places
    place_tags
tags

Вот SQLFiddle

Я просмотрел документацию по Laravel, и самое близкое, на что это похоже, это полиморфное отношение «многие ко многим» , но при этом будет только одна сводная таблица с tag_type что не то, что у меня есть.

Как мне построить этот запрос, чтобы получить книги для каждого места на основе тегов в обеих сводных таблицах? Ответы в MySQL тоже классные, я просто не знаю, как это будет выглядеть как запрос ...

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Вот что я читаю.

Предположим, модель тегов:

class Tag {
      public function books() { 
          $this->belongsToMany(Book::class);
      }
      public function places() {
          $this->belongsToMany(Place::class);
      }
}

Тогда, если вам нужно получить все книги, имеющие общий тег, с конкретным местом, вы можете сделать:

$tagsForPlace = Tag::whereHas("places", function ($query) { $query->where("id", $placeId; })->with("books")->get(); //$PlaceId is the id you are interested in.

Тогда вам нужны только книги:

$booksWithTagsForPlace = $tagsForPlace->map(function ($tag) { 
      return $tag->books; 
})->unique("id"); //Unique to filter out duplicate books if any

Хотя я могу ошибаться в своем понимании вопроса.

0 голосов
/ 16 мая 2018

Как мне построить этот запрос, чтобы получить книги для каждого места на основе тегов в обеих сводных таблицах?Ответы в MySQL тоже классные, я просто не знаю, как это будет выглядеть как запрос ...

Запрос

SELECT 
   books.*
 , places.*
FROM 
 book_tags
INNER JOIN 
 place_tags
ON
 book_tags.tag_id = place_tags.Tag_id

INNER JOIN 
 books
ON
 book_tags.book_id = books.id

INNER JOIN 
 places
ON
 place_tags.place_id = places.id 

Результат

| id |       title | id | name |
|----|-------------|----|------|
|  1 | Science Boo |  1 | Shop |

см. Демонстрацию http://sqlfiddle.com/#!9/f2674d/13

Или используйте псевдонимы столбцов, такие как

Запрос

SELECT 
   books.id AS book_id
 , books.title AS book_title
 , places.id AS place_id 
 , places.name AS place_name
FROM 
 book_tags
INNER JOIN 
 place_tags
ON
 book_tags.tag_id = place_tags.Tag_id

INNER JOIN 
 books
ON
 book_tags.book_id = books.id

INNER JOIN 
 places
ON
 place_tags.place_id = places.id 

Результат

| book_id |  book_title | place_id | place_name |
|---------|-------------|----------|------------|
|       1 | Science Boo |        1 |       Shop |

см. Демонстрацию http://sqlfiddle.com/#!9/f2674d/15

@ RaymondNijland Что неясно?Я хотел бы получить все книги для данного места: P Данные добавлены в sql :) sqlfiddle.com/#!9/f2674d/1

Затем вам нужно добавить

WHERE
  places.name = 'name'

к запросам выше

...