MYSQL Избранный Случайный отчет от каждой Категории

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

id
name
category (int)

Есть несколько сотен тысяч отчетов. Каждый пункт может быть в одном из 7 различных категориями , которые соответствуют категориям стол:

id
category

Я хочу вопрос, который выбирает 1 случайный пункт от каждой категории. Каков лучший способ приблизиться к этому? Я знаю, чтобы использовать Заказ рэндом() , и ОГРАНИЧИВАЮТ 1 для подобных случайных вопросов, но я никогда не делал чего-то вроде этого.

6
nl ja de

4 ответы

Этот вопрос возвращает все пункты, соединенные с категориями в произвольном порядке:

SELECT
c.id AS cid, c.category, i.id AS iid, i.name
FROM categories c
INNER JOIN items i ON c.id = i.category
ORDER BY RAND()

Чтобы ограничить каждую категорию одной, оберните вопрос в , неравнодушные GROUP BY :

SELECT * FROM (
    SELECT
    c.id AS cid, c.category, i.id AS iid, i.name
    FROM categories c
    INNER JOIN items i ON c.id = i.category
    ORDER BY RAND()
) AS shuffled_items
GROUP BY cid

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

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

5
добавлено
@rzymek хотели бы Вы создавать ответ или редактировать существующий выше?
добавлено автор djt, источник
@rzymek ах nevermind, вы правы. У меня был немного отличающийся синтаксис в моем столе, который вызывал проблему! Большое спасибо!
добавлено автор djt, источник
Гм, этот пересмотренный вопрос возвращает приблизительно 1500 рядов для меня
добавлено автор djt, источник
@SalmanA да, я не уверен, что сказать. I' m испытание его на моей DB и it' s возвращение приблизительно 1500 рядов, а не 7.
добавлено автор djt, источник
It' s странный, потому что здесь группирует по категориям id поэтому, если вы получающий приблизительно 1500 рядов, у вас есть 1500 категорий...
добавлено автор rzymek, источник
Выше работ вопроса после нескольких исправлений: , ИЗБРАННЫЙ * ОТ (ВЫБИРАЮТ c.id как cid, c.category, i.id, i.name ОТ категорий c Пункты ВНУТРЕННЕГО ОБЪЕДИНЕНИЯ i НА c.id = i.category РЭНД ORDER BY ()) КАК GROUP BY ShuffeledItems ShuffeledItems.cid
добавлено автор rzymek, источник
@dtj, Салман А уже сделал его, я только делаю несколько исправлений:), Тем не менее, я думаю, что этот вопрос может быть сделан более эффективный.
добавлено автор rzymek, источник

Вот простое решение. Позвольте предполагают, что у вас есть этот стол.

id  name    category
1   A       1
2   B       1
3   C       1
4   D       2
5   E       2
6   F       2
7   G       3
8   H       3
9   I       3

Используйте этот вопрос

select
  c.id,
  c.category,
  (select name from category where category = c.category   group by id order by rand() limit 1) as CatName
from category as c
group by category
0
добавлено
Этот я испытываю понимающие затруднения, как там, кажется, не ссылка на пункты столы, только категории стол
добавлено автор djt, источник
@dtj у меня нет пункта ключевого слова в моем вопросе тогда, что смущает вас? Я дал вам пример, конечно, можно разрешиться после него.
добавлено автор Muhammad Raheel, источник
действительно ли вы уверены GROUP BY и , РЭНД() будет сотрудничать, давая случайное для каждой группы? вызовите я сомневаюсь относительно него.
добавлено автор Sharky, источник

Попробуйте это

SELECT id, name, category from Items where
( 
 select count(*) from Items i where i.category = Items.category 
 GROUP BY i.category ORDER BY rand()
) <= 1

REF: http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/

0
добавлено
этот, я получаю ошибку, что вопрос sub возвращает больше чем 1 ряд
добавлено автор djt, источник
исправленный вопрос
добавлено автор Vikram, источник

Пожалуйста, отметьте: в следующем примере я предполагаю, что ваш стол называют "пунктами" не "Пунктами", потому что вы также сказали, что другой стол назвали "категориями" (второе имя таблицы, не использованное для своей выгоды).

SQL для того, что вы хотите сделать, примерно был бы:

`SELECT items.id AS item_id,
items.name AS item_name,
items.category AS item_category_id,
categories.id AS category_id,
categories.category AS category_name
FROM items, category
WHERE items.category = categories.id
ORDER BY rand()
LIMIT 1`
0
добавлено
Жаль, если это было неясно. Вопрос должен возвратить 7 рядов - 1 соответствие каждому пункту от каждой категории
добавлено автор djt, источник
этот вопрос только возвращает один ряд
добавлено автор djt, источник
По-моему, автор ожидает вопрос, который возвращает 7 рядов, пункт за один рэнд для каждой категории.
добавлено автор rzymek, источник
Этот вопрос возвращает только один ряд. Без ПРЕДЕЛА 1 - все пункты от каждой категории...
добавлено автор rzymek, источник
@ryzmek, да, that' s правильный. Это также что OP, относительно которого попросили по совпадению. OP сказал, и я указываю: "Я хочу вопрос, который выбирает 1 случайный пункт от каждой категории"
добавлено автор Ezra Free, источник
DBA - русскоговорящее сообщество
DBA - русскоговорящее сообщество
1 345 участник(ов)

Общаемся и обсуждаем темы, посвященные DBA, PostgreSQL, Redis, MongoDB, MySQL, neo4j, riak и т.д. См. также: @devops_ru, @kubernetes_ru, @docker_ru, @nodejs_ru Рекомендуем сразу отключить уведомления, чтобы пребывание здесь было полезным и комфортным.

MySQL
MySQL
995 участник(ов)

The group is about MySQL. For code use hastebin.com. Admin: @smlkw

SqlCom.ru - Стиль жизни SQL
SqlCom.ru - Стиль жизни SQL
908 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только MS SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz). Предложения в @sql_ninja

SQL_Ninja
SQL_Ninja
340 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz)