Mysql Выборка один ко многим

  • Автор темы Автор темы Timol
  • Дата начала Дата начала

Timol

Новичок
Есть 2 таблицы order (заказ) и ordered_goods (товары). В каждом заказе может быть от 0 до определенного множества товаров (1 и более). Есть раздел сайта, в котором можно просматривать все заказы, согласно выбранным фильтрам. В таблице ordered_goods содержатся данные по товарам (в случае изменения описания/названия/и т.п. товара, тут останутся те данные, с которыми товар был заказан).

Сейчас запрос в БД выглядит так:

Код:
SELECT order.id, order.user, ordered_goods.name, ...
FROM order
LEFT JOIN ordered_goods ON order.id = ordered_goods.order_id
GROUP BY order.id
WHERE ...

GROUP BY order.id служит для того, чтобы не допустить дублирование вывода заказов, когда в заказе более одного товара.

Также есть фильтр, в котором можно найти все заказы, товары которого содержат определенный товар (WHERE ordered_goods.goods_id = 1)

Появилась задача, в таблице заказов вывести до 10 наименований товаров для каждого заказа.

Подскажите, возможно ли решить данную задачу одним запросом без GROUP BY и так, чтобы не перестал работать фильтр заказов с определенными товарами?
 
Затем, что на 200000 записей разница выполнения запросов с GroupBy - 3 с., без - 1 с., а 2 секунды, это очень существенно. Один или несколько запросов - не важно, вот только если можно решить задачу в один запрос, то лучше в один, иначе придется еще писать логику составления запросов на PHP. Твое предположение касательно синдрома - неуместно, ты "умник", безосновательно ощутивший себя компетентным во всех науках?
 
Это попытка как-то задеть человека, давшего неудобный ответ? :)
Извини, если разочарую, я на подначки не ведусь уже лет десять. Перегорел.
Если тебе не нужна помощь - мог бы просто сказать, мы люди понятливые.
 
group_concat()

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

не всегда 51 запрос дольше одного.
а в твоем случае можно свести к 3м
получение ид заказов подходящих под условие
получение информации из таблицы заказы по найденным ид1,..ид50
получение всех товаров в заказах ид1,..ид50
 
Последнее редактирование:
@antson, спасибо, я как раз обдумываю вариант про несколько запросов. Подскажи, если знаешь (сслку на man): какое ограничение на IN (1,2,x) - т.е. сколько id-шников можно использовать в конструкции IN?

@AnrDaemon, ты сначала оскорбил меня, "диагностировав" мне на кофейной гуще "синдром", а потом решил обвинить меня в том, что я решил тебя задеть... зря я назвал тебя умником. Ты перечитай свое сообщение - в каком из 3ех предложений, заканчивающихся знаком вопроса, тебе померещился ответ? Весь твой пост-"ответ" пропитан неуважением к собеседнику. Веди себя вежливо - и тогда не придется извинятся.
 
@Timol, (максимальный размер sql запроса - постоянная часть ) разделить на (длину единичного идентификатора + 1 или 3 )
а на практике разумная . нет смысла перечислять ид больше 1% от записей
 
GROUP BY order.id служит для того, чтобы не допустить дублирование вывода заказов, когда в заказе более одного товара.

Подумай над этой фразой. У тебя было без group by решение настоящего вопроса. Записи не дублируются, просто результат запроса всегда таблица.
разница выполнения запросов с GroupBy - 3 с., без - 1 с.,
мало того что он тормозит, так еще и позиции заказа отсекает
Зачем тебе in() вероятнее всего позиций, чтоб вытащить id в пхп а после обратно передать в mysql, ты решал эту задачу без group by и без in()
 
Последнее редактирование:
На данный момент group by служит для универсальности запроса (один запрос для всех возможных комбинаций фильтров), так как фильтров больше десятка и несколько из них ведут к таблицам, у которых может быть более 1 строки соответствия. У одного заказа может быть несколько товаров, несколько телефонов клиента и т.п., а вариант поиска может быть такой: найти все заказы с определенным телефоном клиента и определенным товаром. Чтобы получить "отсеченные" group_by данные (при необходимости) использую отдельные доп. запросы к БД по всем таблицам, которые относятся к таблице заказов, как "много к одному" (SELECT id, phone FROM table_phone WHERE id IN (1,2,3,x)). В главном запросе еще есть и LIMIT (для pagination), от которого планирую избавиться со временем, но это уже другая история, так как тормозит он только, если в результате фильтрации получается большой объем данных.

Зачем тебе in() вероятнее всего позиций, чтоб вытащить id в пхп а после обратно передать в mysql, ты решал эту задачу без group by и без in()
Что-то до меня не дошел смысл этой фразы, просьба написать подробнее...

Чем больше читаю информации по своему вопросу, тем больше склоняюсь к мысли, что для оптимизации (скорость выполнения) придется таки составлять разные запросы под разные фильтры, и одним универсальным запросом решить не получится...
 
На данный момент group by служит для универсальности запроса
Это и есть синдром "щелчка пальцами" - сделать всё сразу в один присест, и желательно - не думая о последствиях.
Чем больше читаю информации по своему вопросу, тем больше склоняюсь к мысли
Это хорошо, что вы читаете и анализируете прочитанное. Это говорит о том, что вы небезнадёжны.
Если у вас много близких по смыслу фильтров, попробуйте разбить запрос так, чтобы его части повторялись как можно больше, тогда повторяющиеся запросы на выборку одних и тех же данных будут попадать в кэш сервера БД и отдаваться намного быстрее, чем ваш "универсальный" один запрос за фильтр.
 
Есть поисковый запрос, который найдет набор из скажем 10 id заказов. Дальше in(этих 10) один раз заказов, один раз для позиций.
 
дополню @WMix поисковый запрос может быть к сфинксу (для заказов придется вести основной индекс и дельту перестраивать после каждого заказа или раз в минуту) , но такое извращение в реальности не потребуется.
это уже уровень ебай или алиэкспресс.
 
Сверху