2015-07-06 2 views
2

У меня есть две таблицы MySQL:Как вы определяете, какой матч выбран при запуске `SELECT INNER JOIN WHERE t1.column = t2.column` и есть несколько совпадений?

Продукты

title id hidden categories 
Thing 10 N  12,14, 
Stuff 23 N  12, 
Object 41 Y  13,14 

Изображение

filename  id productid 
aca8t.jpg 1  10 
ev7ha.jpg 2  10 
mscpk.jpg 3  10 
asges.jpg 4  23 
fcuhg.jpg 5  23 
scvfe.jpg 6  41 
vf6kl.jpg 7  41 
fgszy.jpg 8  41 

я создать список названий продуктов и изображений с использованием ЗЕЬЕСТА, как это:

SELECT  t1.title, 
      t1.id, 
      t1.hidden, 
      t1.categories, 
      t2.image 
FROM  products AS t1 
INNER JOIN pimage AS t2 
WHERE  t1.categories LIKE '%$categoryId%' 
AND  t1.id=t2.productid 
AND  NOT t1.hidden='Y' 
GROUP BY id 
ORDER BY id ASC 

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

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

Как я могу изменить инструкцию SQL так, чтобы была выбрана первая фотография (имя файла с наименьшим images.id)?

+0

Вы используете 'GROUP BY' некстати, потому что у вас есть столбцы в' SELECT', которые не в 'GROUP BY'.Следовательно, как документы MySQL * четко *, вы получаете значение из неопределенной строки соответствия (https://dev.mysql.com/doc/refman/5.6/en/group-by-handling.html). –

+0

ваш оператор INNER JOIN не является полным, поскольку вам нужно даже подумать, что он синтаксически действителен. Вы должны использовать ON clouse для объединения столбцов, как описано здесь: http://www.mysqltutorial.org/mysql-inner-join.aspx. Если вы используете USER, вам действительно не нужен INNER JOIN вообще – rgasiore

ответ

2

Попробуйте использовать коррелировала подзапрос вместо join/group by:

SELECT p.*, 
     (SELECT i.image 
     FROM pimage i 
     WHERE p.id = i.productid 
     ORDER BY i.image ASC 
     LIMIT 1 
     ) as image 
FROM products p 
WHERE p.categories LIKE '%$categoryId%' AND 
     p.hidden <> 'Y' 
ORDER BY p.id ASC 
+1

Чтобы получить пинам с наименьшим значением 'id' для каждого продукта, используйте **' ORDER BY i.id ASC' ** в подзапросе. – spencer7593

1

Если это утверждение было выполнено на другой реляционной базе данных (кроме MySQL/MariaDB), он будет выдавать ошибку с сообщением вдоль строки «неагрегаты в списке SELECT, не включенные в GROUP BY».

But A MySQL специальное расширение для GROUP BY позволяет этот запрос выполнить в MySQL, но, как вы заметили, возвращаемые значения для не-агрегатов в списке выбора являются неопределенными, MySQL возвращает значение из ряд.

Обычный шаблон должен использовать функцию агрегации MAX() или MIN() для «управления», значение которого возвращается.

В вашем случае это приведет к возврату минимального значения id, но получение других значений в этой же строке более проблематично. Если вам нужно только вернуть несколько столбцов, вы можете использовать коррелированные подзапросы в списке SELECT.

Другой подход - использовать встроенный просмотр и операцию соединения.

SELECT t1.title 
     , t1.id 
     , t1.hidden 
     , t1.categories 
     , t2.image 
    FROM products t1 
    JOIN (SELECT n.productid 
       , MIN(n.id) AS min_id 
      FROM pimage n 
      GROUP BY n.productid 
     ) m 
     ON m.productid = t1.id 
    JOIN pimage t2 
     ON t2.id = m.min_id 
    WHERE t1.categories LIKE '%$categoryId%' 
    AND t1.hidden='Y' 
    GROUP BY t1.id 
    ORDER BY t1.id ASC 

Этот подход полезен, когда вам нужно вернуть дополнительные столбцы из строки с «минимальным» идентификатором. Например, необходимо также включить в список SELECT,:

 , t2.fee 
     , t2.fi 
     , t2.fo 
     , t2.fum 
Смежные вопросы