Question

Suppose that two tables exist: users and groups.

How does one provide "simple search" in which a user enters text and results contain both users and groups whose names contain the text?

The result of the search must distinguish between the two types.

Was it helpful?

Solution

The trick is to combine a UNION with a literal string to determine the type of 'object' returned. In most (?) cases, UNION ALL will be more efficient, and should be used unless duplicates are required in the sub-queries. The following pattern should suffice:

 SELECT "group" type, name
   FROM groups
  WHERE name LIKE "%$text%"
UNION ALL
 SELECT "user" type, name
   FROM users
  WHERE name LIKE "%$text%"

NOTE: I've added the answer myself, because I came across this problem yesterday, couldn't find a good solution, and used this method. If someone has a better approach, please feel free to add it.

OTHER TIPS

If you use "UNION ALL" then the db doesn't try to remove duplicates - you won't have duplicates between the two queries anyway (since the first column is different), so UNION ALL will be faster.
(I assume that you don't have duplicates inside each query that you want to remove)

Using LIKE will cause a number of problems as it will require a table scan every single time when the LIKE comparator starts with a %. This forces SQL to check every single row and work it's way, byte by byte, through the string you are using for comparison. While this may be fine when you start, it quickly causes scaling issues.

A better way to handle this is using Full Text Search. While this would be a more complex option, it will provide you with better results for very large databases. Then you can use a functioning version of the example Bobby Jack gave you to UNION ALL your two result sets together and display the results.

I would suggest another addition

 SELECT "group" type, name
   FROM groups
  WHERE UPPER(name) LIKE UPPER("%$text%")
UNION ALL
 SELECT "user" type, name
   FROM users
  WHERE UPPER(name) LIKE UPPER("%$text%")

You could convert $text to upper case first or do just do it in the query. This way you get a case insensitive search.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top