Currently I have two MySQL tables
Properties
id name
1 Grove house
2 howard house
3 sunny side
Advanced options
prop_id name
1 Wifi
1 Enclosed garden
1 Swimming pool
2 Swimming pool
As you can see table two contains specific features about the properties
When I only have max 3 options the query below worked just fine. (maybe a little slow but ok) now things have expanded somewhat and i have a max of 12 options that it is possible to search by and its causing me some major speed issues. The query below is for 8 options and as you can see its very messy. Is there a better way of doing what I’m trying to achieve?
SELECT * FROM properties WHERE id in (
select prop_id from advanced_options where name = 'Within 2 miles of sea or river' and prop_id in (
select prop_id from advanced_options where name = 'WiFi' and prop_id in (
select prop_id from advanced_options where name = 'Walking distance to pub' and prop_id in (
select prop_id from advanced_options where name = 'Swimming pool' and prop_id in (
select prop_id from advanced_options where name = 'Sea or River views' and prop_id in (
select prop_id from advanced_options where name = 'Pet friendly' and prop_id in (
select prop_id from advanced_options where name = 'Open fire, wood burning stove or a real flame fire-place' and prop_id in (
select prop_id from advanced_options where name='Off road parking')
)
)
)
)
)
)
)
Like Mike Brant suggest I would consider altering your datamodel to a limit to set and creating a column for each of these in your
propertiestable. But some times the boss comes: “We also need ‘flatscreen tv'” and then you have to go back to the DB and update the scheme and your data access layer.A way to move this logic somehow out if the database it to use bitwise comparison. This allows you to make simple queries, but requires a bit of preprocessing before you make your query.
Judge for yourself.
I’ve put everything in a test suite for you here sqlfiddle
The basic idea is that each property in your table has an id that is the power of 2. Like this:
You can then store a single value in your properties table buy adding up the options:
If you want to find all properties with wifi and a swimming pool you then do like this:
If you just wanted swimming pool this would be it:
Go try out the fiddle