Question

I'm trying out the following query:

SELECT A,B,C FROM table WHERE field LIKE 'query%'
UNION
SELECT A,B,C FROM table WHERE field LIKE '%query'
UNION
SELECT A,B,C FROM table WHERE field LIKE '%query%'
GROUP BY B ORDER BY B ASC LIMIT 5

That's three queries stuck together, kinda sorta. However, the result set that comes back reflects results from query #3 before the results from query #1 which is undesired.

Is there any way to prioritize these so that results come as all for query #1, then all for query #2 then all for query #3? I don't want to do this in PHP just yet (not to mention having to control for results that showed up in the first query not to show in the second and so forth).

Was it helpful?

Solution

Maybe you should try including a fourth column, stating the table it came from, and then order and group by it:

SELECT A,B,C, "query 1" as origin FROM table WHERE field LIKE 'query%'
UNION
SELECT A,B,C, "query 2" as origin FROM table WHERE field LIKE '%query'
UNION
SELECT A,B,C, "query 3" as origin FROM table WHERE field LIKE '%query%'
GROUP BY origin, B ORDER BY origin, B ASC LIMIT 5

OTHER TIPS

Add an additional column with hard-coded values that you will use to sort the overall resultset, like so:

SELECT A,B,C,1 as [order] FROM table WHERE field LIKE 'query%'
UNION
SELECT A,B,C,2 as [order] FROM table WHERE field LIKE '%query'
UNION
SELECT A,B,C,3 as [order] FROM table WHERE field LIKE '%query%'
GROUP BY B ORDER BY [order] ASC, B ASC LIMIT 5

Can you do it as a subselect, something like

SELECT * FROM (
    SELECT A,B,C FROM table WHERE field LIKE 'query%'
    UNION
    SELECT A,B,C FROM table WHERE field LIKE '%query'
    UNION
    SELECT A,B,C FROM table WHERE field LIKE '%query%'
) ORDER BY B ASC LIMIT 5

SELECT distinct a,b,c FROM ( SELECT A,B,C,1 as o FROM table WHERE field LIKE 'query%' UNION SELECT A,B,C,2 as o FROM table WHERE field LIKE '%query' UNION SELECT A,B,C,3 as o FROM table WHERE field LIKE '%query%' ) ORDER BY o ASC LIMIT 5

Would be my way of doing it. I dont know how that scales.

I don't understand the

GROUP BY B ORDER BY B ASC LIMIT 5

Does it apply only to the last SELECT in the union?

Does mysql actually allow you to group by a column and still not do aggregates on the other columns?

EDIT: aaahh. I see that mysql actually does. Its a special version of DISTINCT(b) or something. I wouldnt want to try to be an expert on that area :)

If there isn't a sort that makes sense to order them you desire, don't union the results together - just return 3 separate recordsets, and deal with them accordingly in your data tier.

I eventually (looking at all suggestions) came to this solution, its a bit of a compromise between what I need and time.

SELECT * FROM 
  (SELECT A, B, C, "1" FROM table WHERE B LIKE 'query%' LIMIT 3
   UNION
   SELECT A, B, C, "2" FROM table WHERE B LIKE '%query%' LIMIT 5)
AS RS
GROUP BY B
ORDER BY 1 DESC

it delivers 5 results total, sorts from the fourth "column" and gives me what I need; a natural result set (its coming over AJAX), and a wildcard result set following right after.

:)

/mp

There are two varients of UNION.

'UNION' and 'UNION ALL'

In most cases what you really want to say is UNION ALL as it does not do duplicate elimination (Think SELECT DISTINCT) between sets which can result in quite a bit of savings in terms of execution time.

Others have suggested multiple result sets which is a workable solution however I would caution against this in time sensitive applications or applications connected over WANs as doing so can result in significantly more round trips on the wire between server and client.

I don't understand why the need of union for taking the data from single table SELECT A ,B ,C FROM table WHERE field LIKE 'query%' or field LIKE '%query' or field LIKE '%query%' GROUP BY B ORDER BY B ASC LIMIT 5

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