0

I'm having trouble running a multi-argument search query in MySQL:

    SELECT item.* from item, attr, attr_xref
    WHERE attr_xref.item = item.id
    AND attr.id = attr_xref.attrID
    AND (
      (attr.name = 'city' AND attr.val LIKE '%new york%')
      OR
      (attr.name = 'floor' AND attr.val = 6)
    )

The query is generated dynamically with php, no trouble there.

The problem is though that this query will not return a strict search. It will return items that have either city or floor equal to their search values.

As I can see it the problem is here AND attr.id = attr_xref.attrID This line returns more than one value for items that have more than 1 attribute, removing the OR operator I'll be trying to match a single attribute with several different names and values, but with one ID.

Is there any way to overcome this?

This is a raw example and at runtime I may have more than 2,3 search arguments.

Thank You, looking froward to your help!

EDIT: Got it working by using the SQL query posted in the accepted answer, and just added this:

AND (a_city.id IS NOT NULL
OR a_floor.id IS NOT NULL)
GROUP BY imobil.id
HAVING COUNT(*) = 2

You you want to group your results and then count them, '= 2' means how many arguments have been passed, this will be counted in PHP. Thanks or your help. If your having trouble you might want to read this question

Community
  • 1
  • 1
michaeltintiuc
  • 671
  • 15
  • 31

1 Answers1

1

Add two left joins that will create one column with the attr.val of "floor" and another with the attr.val of "city" and check that at least one is not null.

Something like this:

SELECT 
    item.*
FROM 
    item
JOIN 
    attr_xref ON attr_xref.item = item.id
LEFT JOIN 
    attr a_city ON  a_city.id = attr_xref.attrID 
                AND a_city.name = 'city'
                AND a_city.val LIKE '%new york%'
LEFT JOIN
    attr a_floor ON a_floor.id = attr_xref.attrID
                AND a_floor.name = 'floor'
                AND a_floor.val = 6 
WHERE 
    a_city.id IS NOT NULL 
    OR a_floor.id IS NOT NULL

I didn't test it, but some approach similar to this may work for you.

jordeu
  • 6,711
  • 1
  • 19
  • 19
  • nope, unfortunately, it still shows items that have at least one of the attributes and not both of them. – michaeltintiuc Apr 08 '12 at 17:24
  • although, if I add a_city.id and a_floor to SELECT I can see that those values are NULL, but WHERE doesn't filter them for some reason. – michaeltintiuc Apr 08 '12 at 17:30
  • Thanks, got it working, simply by adding this at the end: AND (a_city.id IS NOT NULL OR a_floor.id IS NOT NULL) group by item.id having count(*) > 1 – michaeltintiuc Apr 08 '12 at 18:07