Inner Join одной рандомной строки

264
08 февраля 2018, 14:41

Имеем две таблицы Videos и Thumbs. Отношение между объектами video и thumb - has many. Одно Video имеет 3 Thumbs.

Задача, одним запросом получить все видео с одной тумбой, выбранной рандомно. Пока что мой запрос выглядит вот так:

SELECT v.id as video_id, t.id as thumb_id
FROM videos v
INNER JOIN thumbs t
ON t.video_id=v.id

Получается результат:

+----------+---------+
| video_id | thumb_id|
+----------+---------+
| 1        |       1 |
| 1        |       2 |
| 1        |       3 |
| 2        |       4 |
| 2        |       5 |
| 2        |       6 |
| 3        |       7 |
| 3        |       8 |
| 3        |       9 |
| 4        |      10 |
| 4        |      11 |
| 4        |      12 |
| 5        |      13 |
| 5        |      14 |
| 5        |      15 |
+----------+---------+

Нужен результат:

+----------+---------+
| video_id | thumb_id|
+----------+---------+
| 1        |       2 |
| 2        |       6 |
| 3        |       7 |
| 4        |      10 |
| 5        |      15 |
+----------+---------+
Answer 1

Если я правильно понял входные условия, то мы имеем:

  • 1ая таблица Videos
  • 2ая таблица Thumbs

Отношения между ними many-to-many, значит есть

  • 3ая таблица Videos_Has_Thumbs

которая содержит 2 поля - Videos_fk и Thumbs_fk. Это указатели на соответствующие поля id в таблицах Videos и Thumbs (У вас поля могут называться по-другому, поэтому я описываю просто алгоритм работы)

Это означает, что нужно получить записи таблицы videos и прикрепить к ним значения из таблицы thumbs.

Так как у нас 3 таблицы, - первая содержит id видео (таблица videos); вторая содержит данные о том, какое видео какие thumbs имеет (таблица videos_has_thumbs); а третья содержит id thumb'ов (таблица thumbs), то очевидно, что нам нужно два джоина:

SELECT
      Videos.id
    , GROUP_CONCAT(Thumbs.id)
FROM Videos
LEFT JOIN Videos_Has_Thumbs ON Videos.id = Videos_Has_Thumbs.Videos_fk
LEFT JOIN Thumbs ON Videos_Has_Thumbs.Thumbs_fk = Thumbs.id
GROUP BY Videos.id;

Сначала мы выбираем все видео (Select from videos).

Потом узнаем, какие у какого видео есть тумбы (join Videos_Has_Thumbs)

И наконец прикрепляем эти тумбы к нужному видео по полученным данным.

После группировки, у нас выводятся наши данные так, как мы хотим их видеть.

Задача, одним запросом получить все видео с одной тумбой, выбранной рандомно

Если у вас имеется параметр, - в данном случае рандомный id тумбы, то запрос можно превратить в Stored Procedure и передавать туда этот параметр, подставляя id тумбы в WHERE.

Про различия между разными видами JOIN'ов можно почитать тут.

Отношения many-to-many всегда строятся с использованием 3ей (junction) таблицы.

Update после комментариев

В случае, если отношения one-to-many (одно видео, может содержать много тумб, но одна тумба может относиться только к одному видео), Ваш запрос будет выглядеть так:

SELECT
      Videos.id
    , GROUP_CONCAT(Thumbs.id)
FROM Videos
LEFT JOIN Thumbs ON Videos.id = Thumbs.id
GROUP BY Videos.id;

Два примера выше выведут колонку со всеми thumbs, которые есть у видео.

Этот пример будет выводить id одной тумбы рандомно:

SELECT
      Videos.id
    , Thumbs_random.id
FROM Videos
LEFT JOIN (
    SELECT
        Thumbs.id,
        Thumbs.Video_id
    FROM Thumbs
    ORDER BY RAND()
) AS Thumbs_random ON Videos.id = Thumbs_random.Video_id
GROUP BY Videos.id
Answer 2

Попробуйте так

SELECT TOP (SELECT TOP 1 COUNT(video_id) FROM videos GROUP BY 
video_id) 
v.id as video_id, t.id as thumb_id
FROM videos v
INNER JOIN thumbs t
ON t.video_id=v.id

READ ALSO
Способ хранения в базе

Способ хранения в базе

Нужно хранить в базе записи о названии иностранного языка и уровне его владения, к примеру:

278
mysql как оптимизировать order by имея 3 join'a

mysql как оптимизировать order by имея 3 join'a

СУБД: mysql percona последней версии

240
Поиск по id в базе данных и запись значений

Поиск по id в базе данных и запись значений

Здравствуйте, есть таблица prices со столбиками (id, model, name, price, warranty) и таблица orders со столбиками (id, denominations, additional, warr, prices, atotal, ophumber, oname, status, date, uid)

287