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.
Related
I want to select all the matching results in a database table with also random results but with the matching results being at the top. With the way, I am doing now I am using two queries first one being the matching query, and if the count is zero I now select random results. I would like to do this with just one query.
You could attempt using a UNION ALL query as follows.
select product_name,price
from marketing_table
where price >=5000 /*user supplied filter*/
and price <=10000 /*user supplied filter*/
union all
select m.product_name,m.price
from marketing_table m
where not exists (select *
from marketing_table m1
where m1.price >=5000 /*user supplied filter*/
and m1.price <=10000 /*user supplied filter*/
)
What I understand from you comment, you may try something simple like this first:
SET #product := 'purse'; -- search term
SELECT * FROM product
ORDER BY product_name LIKE CONCAT('%',#product,'%') DESC, price ASC;
This is the simplest I can think of and it could be a starting point for you.
Here's a demo : https://www.db-fiddle.com/f/31jrR27dFJqYQQigzBqLcs/2
If this is not what you want, you have to edit your question and insert some example data with expected output. Your current question tend to be flagged as too broad and need focus/clarity.
Did you try using a UNION subquery with a LIMIT?
SELECT *
FROM (
SELECT 0 priority, t.*
FROM first_table t
UNION ALL
SELECT 1 priority, t.*
FROM second_table t
)
ORDER BY priority
LIMIT 20
If you do not want to include any second_table records if first_table returns, you would need to do a subquery on the second query to confirm that no rows exist.
SELECT *
FROM (
SELECT 0 priority, t.*
FROM first_table t
UNION ALL
SELECT 1 priority, t.*
FROM second_table t
LEFT JOIN (SELECT ... FROM first_table) a
WHERE a.id IS NULL
)
ORDER BY priority
LIMIT 20
I think it would be possible to use the Common Table Expressions (CTE) feature in MySQL 8, if you are using that version.
https://dev.mysql.com/doc/refman/8.0/en/with.html
I have the following result from a query in mysql (headers: depicao, arricao):
EDDH, EDDK
EDFH, EDDL
EDDS, EDDH
EDDK, EDDH
My problem is now, that I just want one of the rows, IF the data exist in the correlation "EDDH - EDDK" AND "EDDK - EDDH".
The query for this result is something like this:
SELECT DISTINCT p.depicao, p.arricao FROM xyz WHERE xxyyzz = 1
Thanks for your help!
Order the columns in a consistent way with GREATEST and LEAST, then use SELECT DISTINCT to remove duplicates.
SELECT DISTINCT GREATEST(depicao, arricao) as col1, LEAST(depicao, arricao) AS col2
FROM xyz
WHERE ...
I think row_number() does what you want:
select p.*
from (select p.*,
row_number() over (partition by least(p.depicao, p.arricao), greatest(p.depicao, p.arricao) order by rand()) as seqnum
from p
) p
where seqnum = 1;
You can add additional filtering conditions in the subquery, which you seem to have in your query but not your question.
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
Is it possible, using SQL to pull data from different tables, then sort the data according to one column that is in all tables. eg, I have 3 tables. Base, Selects, Sub. They all 3 have a position column,
Select base_layers.position, selects.position, subbases.position
from base_layers,selects,subbases
Order By (alls)position;
That is exactly what I actually want to do... But have a feeling it is not possible.
Use a union:
(I'm assuming you don't want to cross join all 3 tables)
select Position
from
(
select base_layers.position AS Position
from base_layers
union
select selects.position
from selects
union
select subbases.position
from subbases
) x
order by Position ASC;
Your syntax was incorrect. Try this version.
SELECT * FROM
(
SELECT base_layers.position
FROM base_layers
UNION ALL
SELECT selects.position
FROM selects
UNION ALL
SELECT subbases.position
FROM subbases
) tbl ORDER BY tbl.position;
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