This is not problem you will be able to solve simply in SQL.
Important side note: read up on SQL injection. Never, under any circumstances, should you build a query by concatenating variables directly into it.
What you are trying to do -- if you stop and look at it from the database's perspective -- is ask the database to read every row of your table and search for possible matches.
Even if it works, it isn't going to work well, unless you have an extremely small dataset, because the entire table has to be read for each query.
Your comparison, though, is backwards.
You probably don't really want to evaluate this:
city LIKE '%$string%'
state LIKE '%$string%'
'Houston' LIKE '%Houston, TX%' # false!
'TX' LIKE '%Houston, TX%' # also false!
When you consider what your query is asking the server to do, it seems obvious that your logic does not work. The arguments to LIKE
are not in any sense commutative.
What you are actually trying to find is more like this:
'$string' LIKE CONCAT('%',city,'%')
'$string' LIKE CONCAT('%',state,'%')
'Houston, TX' LIKE '%Houston%' # true!
'Houston, TX' LIKE '%TX%' # also true!
You actually need to reverse the comparisons to make the query logically correct.
However, logically correct is still going to perform terribly for larger datasets, because so much work has to be done by the server and none of the shortcuts often available to the query optimizer can be used. This is a brute force approach, essentially the worst approach possible.
The correct solution is far more complicated: You have to tokenize the address in the application and make an intelligent query, which will be an entirely different query, depending on the patterns found in the content of the search box. Once you identify what you believe to be, for example, a state, your WHERE
clause should be specific, and left-anchored:
WHERE state LIKE CONCAT($parsed_state,'%')
Never use a %
at the beginning of a LIKE argument if it can be avoided. Use them only at the end, if you want to have reasonable performance and potentially be able to take advantage of an index on the column.
Tokenizing free-form addresses, even "complete" ones, is no small feat. See, for example, How to parse freeform street/postal address out of text, and into components