It is not clear to me where a LIMIT applies to a UNION
If I have:
SELECT * From table A
where conditions
UNION
SELECT * From table B
where conditions
LIMIT 10
Does the LIMIT 10 apply to the result of the UNION? Or to the select of table B?
What I need is to apply to the result of the UNION
Where is the UNION operator? Anyway the LIMIT of 10 probably applies on the result of the UNION at least in the place you put it.
Straight from the manual:
To use an ORDER BY or LIMIT clause to sort or limit the entire UNION result, parenthesize the individual SELECT statements and place the ORDER BY or LIMIT after the last one. The following example uses both clauses:
(SELECT a FROM t1 WHERE a=10 AND B=1)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2)
ORDER BY a LIMIT 10;
A statement without parentheses is equivalent to one parenthesized as just shown.
In your case:
SELECT * From table A
where conditions
UNION --assuming the union is here
SELECT * From table B
where conditions
LIMIT 10
The limit will be applied to the result of the union.
Related
I have a Jobs and a Companies table, and I want to extract 20 jobs that meet the following criteria:
Jobs only from two (2) named companies
There can at most be 10 jobs per company
I have tried the following SELECT with UNION DISTINCT, but the problem is that the LIMIT 0,10 applies to the whole result set. I want it to apply to each of the companies.
If there aren't 10 jobs per company, then the query should return all the jobs it finds.
SELECT c.name, j.title, j.`desc`, j.link
FROM jobs_job j
INNER JOIN companies_company c ON j.company_id = c.id
WHERE c.name IN ('Company1')
UNION DISTINCT
SELECT c.name, j.title, j.`desc`, j.link
FROM jobs_job j
INNER JOIN companies_company c ON j.company_id = c.id
WHERE c.name IN ('Company2')
ORDER by name, title
LIMIT 0,10
I am new to MySQL, so realise there may be a smarter way to do this instead of with UNION, so any suggestions for improvements are definitely welcome.
Quoting the docs,
To apply ORDER BY or LIMIT to an
individual SELECT, place the clause
inside the parentheses that enclose
the SELECT:
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
Improving on Alex's answer and based on Joe's observation, the following should work in SQLite:
SELECT * FROM
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
In Teradata we can't use union with top queries as it, if you do you get an error, which needs to be tweaked as shown below. Adding solution for Teradata users.
Can anyone give me some pointers to get this working??
I want to combine to queries into one listing with different sorting.
The first will be any business that are a spotlight sorted randomly, then all other listings sorted alphabetically.
This is what I'm using, but the sorting doesn't work.
(SELECT * FROM business_listings WHERE city='Toronto' AND spotlight='1' ORDER by rand())
UNION
(SELECT * FROM business_listings WHERE city='Toronto' AND spotlight='0' ORDER BY busname)
You may not need a UNION, use the CASE clause in ORDER BY like this:
SELECT *
FROM business_listings
WHERE city='Toronto'
ORDER BY CASE
WHEN spotlight='1' THEN FLOOR(RAND()*10)
WHEN spotlight='0' THEN 10
END, busname
What it will do is, sort records using a random value (from 0 to 9) for records having spotlight=1. Whereas all records having spotlight=0 will come later because ORDER BY will use the value 10 as the sort order.
Working Demo: http://sqlfiddle.com/#!2/1bf6e/1
from this SO question
Example Fiddle
Try this:
SELECT *
FROM (SELECT *
FROM business_listings
WHERE city='Toronto'
AND spotlight='1'
ORDER by rand()) as t1
UNION ALL
SELECT *
FROM (SELECT *
FROM business_listings
WHERE city='Toronto'
AND spotlight='0'
ORDER BY busname) as t2
Assuming table1 and table2 both have a large number of rows (ie several hundred thousand), is the following an inefficient query?
Edit: Order by field added.
SELECT * FROM (
SELECT title, updated FROM table1
UNION
SELECT title, updated FROM table2
) AS query
ORDER BY updated DESC
LIMIT 25
If you absolutely need distinct results, another possibility is to use union all and a group by clause instead:
SELECT title FROM (
SELECT title FROM table1 group by title
UNION ALL
SELECT title FROM table2 group by title
) AS query
group by title
LIMIT 25;
Testing this without the limit clause on an indexed ID column from two tables with ~920K rows each in a test database (at $work) resulted in a bit over a second with the query above and about 17 seconds via a union.
this should be even faster - but then I see no ORDER BY so what 25 records do you actually want?
SELECT * FROM (
SELECT title FROM table1 LIMIT 25
UNION
SELECT title FROM table2 LIMIT 25
) AS query
LIMIT 25
UNION must make an extra pass to fetch the distinct records, so you should use UNION ALL.
Yes, use order by and limits in the inner queries.
SELECT * FROM (
(SELECT title FROM table1 ORDER BY title ASC LIMIT C)
UNION
(SELECT title FROM table2 ORDER BY title ASC LIMIT C)
) AS query
LIMIT 25
This will only go through C rows instead of N (hundreds of thousands). The ORDER BY is necessary and should be on an indexed column.
C is a heuristic constant that should be tuned according to the domain. If you only expect a few duplicates, C=50-100 is probably ok.
You can also find out this for yourself by using EXPLAIN.
SELECT
....
GROUP BY
c.city_id
ORDER BY p.name desc
UNION
SELECT
...
GROUP BY
c.city_id, p
ERROR 1221 (HY000): Incorrect usage of UNION and ORDER BY
is there a way to have this format because i want the top query to have an orderby do i need to have the same orderby on the bottom query
The ORDER By comes at the end
select *
from..
union all
select *
from...
order by....
what you can do if you want the first query to show up first is this
select *, 1 as SortOrder
from..
union all
select * ,2 as SortOrder
from...
order by SortOrder,<other columns>...
ORDER BY should be at the end of your select statement, not before the UNION.
See here and here for more information on UNION syntax.
You can't use an order by on the select queries that will be joined by the UNION. You can, if you want, select everything afterwards and add an order by then.
In standard SQL, the ORDER BY comes at the end of the UNION'd queries and is applied to the final result from those queries.
But...
MySQL allows you to use an ORDER BY within a UNION statement if you enclose it in brackets:
( SELECT ....
FROM ...
GROUP BY c.city_id
ORDER BY p.name DESC )
UNION
SELECT ...
FROM ...
GROUP BY c.city_id
...which'll also allow you to use LIMIT...
As the other answers say, It is being parsed as
SELECT { unordered_stuff UNION SELECT unordered_stuff } ORDER BY foo
Some, though I don't believe all, databases support an alternate disambigiouation syntax. This is from the Pg lists.
(SELECT * from foo where priority = 1 order by seniority)
UNION ALL
(select * from foo where priority > 1 order by seniority, priority)
Otherwise the ORDER BY is considered to apply to the whole UNION result
(it's effectively got lower binding priority than the UNION). Note also
that you *must* use UNION ALL, else UNION will attempt to eliminate
duplicates, and mess up the sort order while at it.
See also Bruno's solution nearby. Not sure which of these approaches
would be faster; try both.
I'am trying to understand what causes the following, maybe you could help me:
I have a query like:
select field1,fieldDate from table1
union all
select field1,fieldDate from table2
order by fieldDate desc
and the another one like this:
select field1,field2,fieldDate from table1
union all
select field1,field2,fieldDate from table2
order by fieldDate desc
So basically they are the same with the exception that in the second I retrieve an extra field.
Now, both results come with a diferent ordering, but just for the cases that the dates are exacly the same. For example there are 2 rows (row1,row2) with date 2009-11-25 09:41:55. For query 1 row1 comes before row2 and for query 2 row2 comes before row1.
Does somebody knows why this happens?
Thanks,
Regards
The ordering based on any fields that you don't explicitly order by is undefined, and the optimizer can change the ordering if it thinks that results in a better execution plan. Given two rows with the exact same value in the order by field you can not depend on them being in any particularly order in relation to each other unless you explicitly order by another field with different values.
Can you do this
select * from ( select
field1,field2,fieldDate, 0 as ordercol from table1
union all select
field1,field2,fieldDate, 1 as ordercol from table2) t1
order by fieldDate desc, ordercol asc
Straight from the MySQl manual, to user order by on a union you have to parenthesis the individual tables.
(select field1,fieldDate from table1)
union all
(select field1,fieldDate from table2)
order by fieldDate desc
This is not SQL standards compliant! The code you entered should order the union of both tables but to my surprise MySQL has the above syntax.
The order in which rows with the same fieldDate are returned can differ for each query execution. Usually this order will be the same but you should not count on it. If you want any extra ordering state more order by fields.
EDIT: This answer is wrong: the order by works on the entire union. I'll leave it here to save others the trouble :)
Your order by only works on the second part of the union. You can use a subquery to make the order by work on the entire union:
select field1,field2,fieldDate
from (
select field1,field2,fieldDate
from table1
union all
select field1,field2,fieldDate
from table2
) SubQueryName
order by fieldDate desc