2015-12-31 4 views
0

У меня есть следующий запрос:группы MySQL по содержит

select *, group_concat(tags.tag_name separator ',') as tags from games 
left join game_info using(game_id) 
left join game_tags using(game_id) 
left join tags on(tags.tag_id = game_tags.tag_id) 
group by games.game_id; 

Есть ли способ для меня, чтобы отфильтровать результаты, где группа имеет особое значение?

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

select *, group_concat(tags.tag_name separator ',') as tags from games 
left join game_info using(game_id) 
left join game_tags using(game_id) 
left join tags on(tags.tag_id = game_tags.tag_id) 
group by games.game_id 
having tags like '%puzzle%'; 

ответ

0

Поскольку фильтрации на конечный результат (tags), более эффективное заявление, скорее всего, нет. Возможны вариации в заявлении, и вы можете проверить их, чтобы убедиться, что они более эффективны.

Примечание: В вас SELECT есть * без GROUP BY функции. Это приведет к случайному возврату списка значений *, длинному списку повторений значений tags или вообще не группированию (ошибка в запросе). Примените функцию ко всем возвращаемым значениям столбца, чтобы вы контролировали, какое значение возвращается.

Возможный альтернативный запрос:

Сначала выберите все game_ids, которые делают ваш% головоломка%

SELECT DISTINCT tag_id FROM tags WHERE tag_name LIKE '%puzzle%' 

Вступить в спину на игры, чтобы получить все game_ids где game_id имеет% головоломка% и другие значения:

SELECT game_id,group_concat(tags.tag_name separator ',') as tags 
FROM games gs 
INNER JOIN game_tags gt ON gs.game_id=gt.game_id 
INNER JOIN (
    SELECT DISTINCT tag_id FROM tags WHERE tag_name LIKE '%puzzle%') q 
    ON gt.tag_id=q.tag_id 
GROUP BY gs.game_id; 

Поскольку HAVING отфильтровали любые несоответствующие данные, вместо LEFT JOIN можно использовать INNER JOIN, часто ускоряя запрос.

Использование *замечания сверху, таблица game_info может быть удалена из запроса, так как он не будет ничего в итоге сделать.

Смежные вопросы