tags:

views:

2078

answers:

8

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, kindasorta. However, the result set that comes back reflects results from query #3 BEFORE results from query #1 (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).

Cheers,

edit: many thanks to all! the solution turned out to be a mix of all answers. worked beautifully!.

/mp

+2  A: 

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
Mark Harrison
A: 

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.

Greg Hurlman
+3  A: 

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
Yaakov Ellis
+5  A: 

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
Mario Marinato -br-
A: 

Thanks! 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

mauriciopastrana
+1  A: 
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 :)

svrist
A: 

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.

A: 

Is there any (clean) possibility to put a header like f.e. "results select#1", "results select#2" etc before the several result-blocks?

greets, maschek

maschek
You have to create separate question, not dig for 2 years old questions
zerkms
but my question is regarding this toppic. so its better to place the question here without posting the same thing again.
maschek
so only answer comes from some kind of blockwart. funny.
maschek