I want to filter a OSM file by several criterias by combining several AND and OR operators via Layer Properties -> Source -> Query Builder. My filter looks like:

"highway" in ('secondary','tertiary','unclassified','residential','secondary_link','tertiary_link','living_street','service','services','road','rest_area','yes') 
and ("waterway" IS NULL or "waterway" in ('no'))
and ("barrier" IS NULL or "barrier" in ('no'))
and ("maxspeed" IS NULL or "maxspeed" in ('5','10','15','20','25','30','35','40','45','50','55','60') or "maxspeed" <= 60)
and ("access" IS NULL or "access" in ('allowed','*','public','residential','services','unknown','yes','bus'))
and ("tunnel" IS NULL or "tunnel" in ('no'))

However, it returns all features. Maxspeed currently is a String field, but thats not always the case.

How do I set up a complex filter expression for QGIS 3 correctly, or to be more specific, how do I combine several AND and OR operators?

  • Is the maxspeed a numeric or string field? If it is numeric, the in('5','10' etc part would not filter out anything that <= 60 does not filter out. (If it is a string, you are officially allowed to hate the person who set up the data set :-D ) – MortenSickel Mar 20 '20 at 12:50
  • @MortenSickel unfortunately it is currently a string because someone added a value 100 mph... but usually it should be a numerical value. – MrXsquared Mar 20 '20 at 12:59

The and/or look fine. Considering maxspeed as both a string and a number is wrong and is likely to throw an error, which in turn could be interpreted as no filter. Try removing the "maxspeed" <= 60.

Eventually, cast this field to a number first, so you can always compare with a number instead of a string


If you get too many features in such an expression, the problem is often a stray 'or'. To me it looks as if you have got everything right here, but you are asking for quite a lot... are you sure you are not querying for the entire data set?

Do you also get the barriers and waterways? If so, try to remove the "is null" part and see what is happening. Also, when you are just querying for one item, I would use = and not in, e.g.

and ("waterway" IS NULL or "waterway" = 'no')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.