Любой гуру MySQL там? Группировка ПОСЛЕ заказа (альтернатива подзапросам) - PullRequest
1 голос
/ 19 сентября 2009

Я присоединяюсь к 3 таблицам. последний содержит несколько фотографий на предмет. Идея состоит в том, чтобы получить одну запись для каждого предмета, и только одна фотография была выбрана случайным образом. ЗАКАЗ меняется, ГДЕ меняется. Лучшее, что я мог получить, это подзапрос. Есть более эффективный способ сделать это?

SELECT *
FROM (
    SELECT *
    FROM art
    LEFT JOIN prov USING ( provID )
    LEFT JOIN photos USING ( artID )
    WHERE artBrand = "Shimano" AND catID=5 AND (stock1>0 OR stock2>0) AND itemName LIKE "%20mm%" 
            //the WHERE changes wildly, this is only an example
   ORDER BY rand( ) // sometimes is rand, sometimes price, sometimes stock...
)rand
GROUP BY artID // this is the only reasonable way i've got so far to avoid duplicates when an article has more than 1 photo

LIMIT x // меняется, иногда мне нужно показать все статьи, которые соответствуют поисковому запросу, иногда мне нужно всего несколько (5 или 10)

Важно: этот запрос РАБОТАЕТ. Но мне нужен более эффективный способ сделать это. Подзапросы очень дороги.

Обновление:

  • Мне нужно другое фото каждый раз
  • Я ищу самый быстрый запрос (в этом суть моего вопроса).
  • Сортировка товаров различается, иногда мне нужно использовать цену, иногда название, иногда случайное ...
  • В некоторых статьях нет фотографии, поэтому я использую левое соединение. Я не могу их выпустить.
  • Некоторые статьи имеют 10, 15 или даже 20 фотографий.
  • Но в некоторых случаях мне нужно показать только с сочленением с фотографией
  • ГДЕ может иметь до 20 условий и быть очень сложным. Это только упрощение.

Упрощенные структуры таблиц:

Table art
artID: int
artName: varchar
artBrand: varchar
artPrice: decimal
provID: int
photo: int (when there is at least one available photo this is set to 1)
many more rows

Table prov
provID: int
provName: varchar
many more rows

Table photos
artID: int
thumb: varchar
normal: varchar
big: varchar
nothing fancy

Ответы [ 3 ]

2 голосов
/ 29 сентября 2009

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

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

1 голос
/ 26 сентября 2009

Рассматривали ли вы возвращение всех фотографий в вашем запросе и случайного выбора фотографии на уровне приложения? Если у вас есть только несколько фотографий для каждого объекта, это может быть не так дорого, как вы думаете. Возможно, стоит попробовать.

0 голосов
/ 19 сентября 2009

ОК, так как вы добавили больше объяснений, позвольте мне переписать мой ответ. Прежде всего вам нужен первичный ключ для таблицы фотографий, следуя вашим правилам именования, я называю его photoID

SELECT 
    *,
    (SELECT photoID FROM photos 
        WHERE artID=art.artID
        ORDER BY rand() LIMIT 1
    ) AS randPhoto, /*single random image of this item*/
    (SELECT thumb FROM photos WHERE photoID=randPhoto) AS thumb,
    (SELECT someotherfield FROM photos  WHERE photoID=randPhoto) AS otherfield,
FROM art
   LEFT JOIN prov USING ( provID )
WHERE artID >20
        AND artID <40

Нет необходимости группировать по

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...