I have the following SQL-Statement:
(SELECT animation_id,
animation_name,
animation_group
FROM animations
WHERE animation_id = '45')
UNION ALL
(SELECT animation_id,
animation_name,
animation_group
FROM animations
WHERE animation_id <> '45'
AND active = TRUE
ORDER BY animation_group,
animation_name)
The table looks like this:
The sorting is not OK. I wanted that the data is being sorted by the column "animation_group", but the result is sorted after "animation_id" I think. Look at the screenshot, which shows the output:
If it is relevant: It is MySQL. The Statement is beeing called through PHP.
Is the SQL-Statement correct?
Thank you!
EDIT: The base of my request or lets say the reason why I use the UNION is the following:
The result of the first select should always be the first row. The result of the second select should be ordered by. Therefore I don't want to order the whole result.
First of all there is no group by
rather the issue is with order by
. Second, don't see why you need a UNION
here. You can change your query to be like below using a OR
condition probably
SELECT animation_id, animation_name, animation_group
FROM animations
WHERE animation_id = '45'
OR (animation_id <> '45' and active = true)
ORDER BY animation_group, animation_name;
Manually add a sort ordering for the selected item:
SELECT
animation_id,
animation_name,
animation_group,
CASE WHEN animation_id = '45' THEN 1 ELSE 0 END AS is_selected
FROM
animations
WHERE
animation_id = '45' OR (animation_id <> '45' AND active = true)
ORDER BY
is_selected DESC,
animation_group,
animation_name
If you still want to keep your UNION
for some reason:
SELECT
animation_id,
animation_name,
animation_group,
1 AS is_selected
FROM
animations
WHERE
animation_id = '45'
UNION ALL -- If animation_id is unique, I can't see why you'd need a UNION ALL here, by the way
SELECT
animation_id,
animation_name,
animation_group,
0 AS is_selected
FROM
animations
WHERE
animation_id <> '45' AND
active = true
ORDER BY
is_selected DESC,
animation_group,
animation_name
Also, assuming animation_id
is a unique integer, 1) you don't need UNION ALL, as each row selected will be unique anyway, and 2) you don't need the quotes around the values, ie just animation_id = 45
will work, rather than animation_id = '45'
.
try this
SELECT * FROM (
SELECT animation_id, animation_name, animation_group
FROM animations
WHERE animation_id = '45'
UNION ALL
SELECT animation_id, animation_name, animation_group
FROM animations
WHERE animation_id <> '45' and active = true
) as tmp_table
ORDER BY animation_group, animation_name;
Just don't enclose the order by inside parentheses. Doing so, performs the order by for the second query only and not the result. Moreover, UNION is free to reorder results. An order by after one or more UNION applies to the result of the unions, but only if you don't change its scope using parentheses. Your query will work if you remove parentheses.
"UNION ALL -> ORDER BY not working as expected" -- indeed, it's not working as expected, it is working as documented :
Use of
ORDER BY
for individualSELECT
statements implies nothing about the order in which the rows appear in the final result becauseUNION
by default produces an unordered set of rows. Therefore, the use ofORDER BY
in this context is typically in conjunction withLIMIT
, so that it is used to determine the subset of the selected rows to retrieve for theSELECT
, even though it does not necessarily affect the order of those rows in the finalUNION
result. IfORDER BY
appears withoutLIMIT
in aSELECT
, it is optimized away because it will have no effect anyway.To use an
ORDER BY
orLIMIT
clause to sort or limit the entireUNION
result, parenthesize the individualSELECT
statements and place theORDER BY
orLIMIT
after the last one.
Following the documentation advice, your query should be:
(
SELECT animation_id, animation_name, animation_group
FROM animations
WHERE animation_id = '45'
)
UNION ALL
(
SELECT animation_id, animation_name, animation_group
FROM animations
WHERE animation_id <> '45' and active = true
)
ORDER BY animation_group, animation_name
More, your query selects the record that have either animation_id = 45
OR active = true
and therefore it can be written as:
SELECT animation_id, animation_name, animation_group
FROM animations
WHERE animation_id = '45' OR active = true
ORDER BY animation_group, animation_name
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.