MYSQL присоединяет случайную строку из другой таблицы для каждой строки

#mysql #join #random #greatest-n-per-group #window-functions

#mysql #Присоединиться #Случайный #наибольшее число на группу #окно-функции

Вопрос:

У меня есть две таблицы: Продукты питания и ингредиенты (см. Изображение 1 ниже).

Изображение 1
введите описание изображения здесь

Я хочу рандомизировать ингредиенты для каждого продукта (могут быть повторяющиеся ингредиенты для всех продуктов). Как использовать запрос для получения цены тоже? Спасибо

Я пытался использовать приведенный ниже SQL, но не тот результат, который я хотел (см. Изображение 2), потому что при использовании sample SQL 1 ингредиенты гарантируются одинаковыми для всех строк. При использовании sample SQL 2 цена также рандомизирована, не соответствует соответствующим ингредиентам.

 /* sample SQL 1 */
select a.description, b.description, b.price
from Foods a
join (select a1.* from Ingredients a1 order by rand() limit 1) b
;

/* sample SQL 2 */
select a.description, (select a1.description from Ingredients a1 order by rand() limit 1) as description, (select a1.price from Ingredients a1 order by rand() limit 1) as price
from Foods a
  

Изображение 2
введите описание изображения здесь

Комментарии:

1. Как вы можете определить разницу между description и description?

2. Извините, я понял, что вы имели в виду, первое — это описание блюда, второе — описание ингредиента. Я хочу рандомизировать ингредиент для каждой строки в таблице Foods, а не только для всех продуктов с одинаковыми рандомизированными ингредиентами. Спасибо

Ответ №1:

Если вы используете MySQL 8.0, вы можете использовать row_number() для этого:

 select *
from (
    select 
        f.description as food, 
        i.description as ingredient, 
        i.price,
        row_number() over(partition by f.id order by random()) rn
    foods f
    cross join ingredient i
) t
where rn = 1
  

Ответ №2:

Это также работает со старыми версиями базы данных MySQL.

 SELECT food, indeg, MAX(rn)
FROM (
       SELECT x.*, @rn := @rn   1 AS rn
       FROM ( SELECT f.description AS food, i.description AS indeg
              FROM Foods f
              JOIN Ingredients i
              ORDER BY RAND()
             ) x
       JOIN (SELECT @rn := 0) r
    ) a
GROUP BY food