Грязное самостоятельное присоединение Mysql SELECT - PullRequest
2 голосов
/ 02 февраля 2012

Мне нужно вернуть список идентификаторов продуктов, которые ...

  1. В пределах определенной категории (например, "Одежда")
  2. , которые имеют различные атрибуты, такие как«Красный» или «Зеленый»
  3. которые сами находятся в атрибутных «группах», таких как «Цвет»

Я застреваю, когда мне нужно выбрать параметры атрибута MULTIPLE в MULTIPLEгруппы атрибутов.Например, если мне нужно вернуть список продуктов, где цвет «синий» ИЛИ «красный» И размер «средний» ИЛИ «XXL».

Это мой код:

SELECT `products.id` 
FROM 
`products` , 
`categories` ,
`attributes` att1, 
`attributes` att2   
WHERE products.id = categories.productid 
AND `categories.id` = 3 
AND att1.productid = products.id
AND att1.productid = att2.productid
AND 
(att1.attributeid = 58 OR att1.attributeid = 60)
AND 
(att2.attributeid = 12 OR att2.attributeid = 9)

Я считаю, что этот код работает, но он выглядит довольно грязно, и я не уверен, что мое «грязное» самостоятельное объединение - правильный путь.У кого-нибудь есть идеи по поводу более «элегантного» решения моей проблемы?

Ответы [ 2 ]

5 голосов
/ 02 февраля 2012

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

SELECT products.id
FROM products 
join categories on products.id = categories.productid
join attributes att1 on att1.productid = products.id 
join attributes att2 on att1.productid = att2.productid
WHERE categories.id = 3 
AND att1.attributeid IN (58, 60)
AND att2.attributeid IN (12, 9)

Его легче читать, потому что он явно демаркирует объединяет условия из условия фильтрации строк условия. Оптимизатору SQL также легче идентифицировать эти различия и создавать лучшие планы запросов

1010 * Отредактировано * Я также добавил использование IN (...). Мало того, что это выглядит лучше, БД будет использовать индекс с IN, но обычно не с OR, даже если они означают одно и то же

4 голосов
/ 02 февраля 2012
SELECT p.id 
FROM   products p
JOIN   categories  c ON  c.productid = p.id
JOIN   attributes a1 ON a1.productid = p.id
JOIN   attributes a2 ON a2.productid = p.id
WHERE  categories.id = 3 
AND    a1.attributeid IN (58, 60)
AND    a2.attributeid IN (12,  9)

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

Если подумать, это может быть преднамеренным, и мое исправление неверно. Тем не менее, смешивать атрибуты с группами атрибутов в одной таблице довольно сложно.

Я также упростил ваш синтаксис и использую явные соединения, которые более читабельны.

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