2010-07-26 3 views
1

У меня возникла проблема с получением некоторых данных.
таблицы У меня есть (для целей тестирования):Поиск продуктов с несколькими критериями

продукты:

 
product_id  | product_name 
----------------------------- 
1    | product 1 
2    | product 2 
3    | product 3 

Атрибуты:

 
product_id  | attribute_id  | attribute_value 
------------------------------------------------------- 
1    | 1     | lorem 
1    | 2     | ipsum 
2    | 1     | lorem 
2    | 2     | doler 
3    | 1     | sit 
3    | 2     | ipsum 

Я хочу, чтобы найти продукты, которые имеют Lorem хранятся в attribute_id 1 И Ipsum хранится in attribute_id 2.

Если я использую этот запрос,

 
SELECT 
    attributes.attribute_id, 
    attributes.attribute_value, 
    products.product_id 
FROM 
    products 
    Inner Join attributes ON products.product_id = attributes.product_id 
WHERE 
    (attributes.attribute_id = 1 AND attributes.attribute_value = 'lorem') 
OR 
    (attributes.attribute_id = 2 AND attributes.attribute_value = 'ipsum') 

я получаю:

 
attribute_id   | attribute_value  | product_id 
---------------------------------------------------------- 
1     | lorem    | 1 
2     | ipsum    | 1 
1     | lorem    | 2 
2     | lorem    | 3 

Но я действительно хочу, чтобы получить этот результат:

 
attribute_id_1 | attribute_id_2 | attribute_value_1 | attribute_value_2 | product_id 
---------------------------------------------------------- 
1    | 2    | lorem    | ipsum    | 1 

Или просто PRODUCT_ID 1 в результате.

Я могу заставить его работать со следующим запросом, но в процессе производства (с большим количеством данных и несколькими объединениями) это ПУТЬ для замедления.

 
SELECT 
    products.product_id 
FROM 
    products 
    Inner Join attributes ON products.product_id = attributes.product_id 
WHERE 
    attributes.attribute_value = 'ipsum' 
AND 
    products.product_id IN (
     SELECT 
     products.product_id 
     FROM 
     products 
     Inner Join attributes ON products.product_id = attributes.product_id 
     WHERE 
     attributes.attribute_value = 'lorem' 
) 

Надеюсь, вы понимаете, что я пытаюсь сделать.

Может кто-нибудь, пожалуйста, помогите мне?
Спасибо!

ответ

0

Не могли бы вы взять первый (сломанный) запрос, группу по product_id, а затем добавить статью HAVING COUNT(*) = 2?

+0

Это может работать .. Если ответ Брайана не работает, я попробую это. Благодаря! – Johan

+0

Нет проблем :) Удачи ... – pdbartlett

+0

Ну, потому что моя производственная установка немного сложнее, чем мой пример, ваш ответ работает и является лучшим вариантом для меня. Еще раз спасибо. – Johan

0

Цитата:

attribute_id_1 | attribute_id_2 | attribute_value_1 | attribute_value_2 | product_id 
---------------------------------------------------------- 
1    | 2    | lorem    | ipsum    | 1 

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

select Products.* from Products,Attributes WHERE 
Products.product_id = Attributes.product_id 
AND ((Attributes.attribute_value='ipsum' AND Attributes.attribute_id='1') OR (Attributes.attribute_value='lorem' AND Attributes.attribute_id='2')) GROUP by Products.product_id; 
+0

Мне нужно найти продукты, в которых lorem хранится в атрибуте_id 1 И ipsum, хранящемся в атрибуте_ид 2, а не как в моем примере. С помощью этого запроса я получаю их все. Но спасибо за ответ. – Johan

+0

Затем используйте 'QUERY 1' UNION 'QUERY 2' см. MySQL doc on UNION. – Youssef

0
SELECT * FROM products p 
INNER JOIN attributes a USING (product_id) 
WHERE a.attribute_value IN ('lorem','ipsum') 
+0

Таким образом, я получаю все продукты, а не те, у которых оба значения. – Johan

0

Поскольку первые четыре колонок все фиксированные, нет необходимости выбирать их. Все, что вам нужно, это идентификатор продукта; Вы можете получить это путем ...

SELECT product_id 
    FROM products 
    WHERE EXISTS (SELECT * 
         FROM attributes 
         WHERE attributes.product_id  = products.product_id AND 
          attributes.attribute_id = 1     AND 
          attributes.attribute_value = 'lorem') 
        AND 
      EXISTS (SELECT * 
         FROM attributes 
         WHERE attributes.product_id  = products.product_id AND 
          attributes.attribute_id = 2     AND 
          attributes.attribute_value = 'ipsum'); 

Если вы действительно должны иметь фиксированные столбцы на выходе, можно попробовать ...

SELECT 1 AS attribute_id_1, 
     2 AS attribute_id_2, 
     'lorem' AS attribute_value_1, 
     'ipsum' AS attribute_value_2, 
     product_id 
    FROM ...etc... 
+0

Эй, Брайан, я думаю, это сработает ... Я попытаюсь использовать его в своей производственной базе данных. Благодаря! – Johan

+0

Этот ответ идеально подходит для моего примера выше, но я не могу заставить его работать в моей производственной среде. Но еще раз спасибо. – Johan

0
Select 
a1.attribute_id attribute_id_1, 
a2.attribute_id attribute_id_2, 
a1.attribute_value attribute_value_1, 
a2.attribute_value attribute_value_2, 
p.product_id 
from products p 
inner join attributes a1 on a1.product_id = p.product_id and a1.attribute_id = 1 
inner join attributes a2 on a2.product_id = p.product_id and a2.attribute_id = 2 
where a1.attribute_value='lorem' 
and a2.attribute_value='ipsum'; 
Смежные вопросы