سؤال

I need to make search for an object by specific attributes. I have a table item_attribute:

item_attribute             item_attribute_type_fk            item_fk              value_text

     1                        1                   1              bbbb
     2                        2                   1           450-240-310
     3                        3                   1             800x250
     4                        4                   1               2,2
     5                        1                   2               HBO

etc

I've tried this:

SELECT item,name,sale_price,producer,producer_code,store_price,I.type_name 
FROM ((item INNER JOIN unit_type ON unit_type_fk=unit_type) 
INNER JOIN item_store ON item=item_fk)AS I 
INNER JOIN item_attribute AS A ON I.item=A.item_fk 
WHERE store_price BETWEEN 200.0 AND 300.0 
AND (UPPER(value_text) LIKE UPPER('%b%') AND item_attribute_type_fk=1) 
AND (UPPER(value_text) LIKE UPPER('%2%') AND item_attribute_type_fk=4) 
GROUP BY item,I.type_name ORDER BY item

Result should be row, where item_fk = 1, but in reality select returns zero rows. If I change AND to OR between attributes that will result in several rows, which is not exactly what I want, because search need to return only that object, that has all attributes, that user typed in in search field. How should I change code, that it will look for a value only through attributes with specific item_attribute_type_fk and return row with object, that has all that attributes?

هل كانت مفيدة؟

المحلول

You appear to be using an EAV-like schema.

To query multiple values in EAV you have to join the same table multiple times. e.g.

SELECT item,name,sale_price,producer,producer_code,store_price,I.type_name 
FROM 
  item 
  INNER JOIN unit_type ON unit_type_fk=unit_type
  INNER JOIN item_store ON item=item_fk)AS I 
  INNER JOIN item_attribute AS a1 ON I.item = a1.item_fk 
  INNER JOIN item_attribute AS a2 ON I.item = a2.item_fk   -- note second join
WHERE store_price BETWEEN 200.0 AND 300.0 
  AND (UPPER(a1.value_text) LIKE UPPER('%b%') AND a1.item_attribute_type_fk=1) 
  AND (UPPER(a2.value_text) LIKE UPPER('%2%') AND a2.item_attribute_type_fk=4) 
GROUP BY item, I.type_name
ORDER BY item

Consider transitioning to using json or hstore for your attributes. It's lots less painful to query.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top