问题
I am trying to run the below query but looks like I am doing something wrong.
(Just modified the sample query for clear understanding)
SELECT name,total,rate
FROM business b
WHERE rate > 100
ORDER BY total DESC
UNION
SELECT name,total,rate
FROM business b
WHERE rate <= 100
ORDER BY rate ASC
Now I want to union of these two queries and in the resultant output in first row the output should come from first query and then output from second query in the same sorted order however the single actual query was giving.
Let me know if it is still unclear. I will try to explain in some more deep level.
回答1:
It's really simple: Use UNION ALL
instead of UNION
.
SELECT * FROM (
SELECT name,total,rate
FROM business b
WHERE rate > 100
ORDER BY total DESC) x
UNION ALL
SELECT * FROM (
SELECT name,total,rate
FROM business b
WHERE rate <= 100
ORDER BY rate ASC) y
UNION ALL preserves order as coded.
UNION removes duplicates and does not guarantee order. Most databases actually sort the output (to make duplicate detection easier).
回答2:
Try this:
select name,total,rate
from (
SELECT name,total,rate, row_number() over(order by total desc) rn, 1 ord
FROM business b
WHERE rate > 100
UNION
SELECT name,total,rate, row_number() over(ORDER BY rate ASC) rn, 2 ord
FROM business b
WHERE rate <= 100
)
order by ord, rn
回答3:
Add a branch flag in each of the inner branches, and sort by that first:
SELECT * FROM
(
SELECT * FROM
(
SELECT 'd' AS char1 , 2 AS sortcol, 1 AS branch FROM dual
UNION
SELECT 'c' AS char1 , 1 AS sortcol, 1 AS branch FROM dual
ORDER BY sortcol
) Inner1
UNION
SELECT * FROM
(
SELECT 'a' AS char1 , 1 AS sortcol, 2 as branch FROM dual
UNION
SELECT 'b' AS char1 , 2 AS sortcol, 2 as branch FROM dual
ORDER BY sortcol
) Inner2
) Outer
ORDER BY Outer.branch, Outer.SORTCOL;
CHAR1 SORTCOL BRANCH
----- ---------- ----------
c 1 1
d 2 1
a 1 2
b 2 2
Obviously you can replace *
in the outer query to only get the columns you want in the result set, excluding both branch
and sortcol
.
SQL Fiddle with both queries for comparison.
回答4:
EDIT: Try conditional OR clause as here. This will also avoid unions.
SELECT NAME, TOTAL, RATE FROM BUSINESS B
ORDER BY
CASE
WHEN rate > 100 THEN total
WHEN rate <= 100 THEN rate
END
Instead of using multiple layers of select query, Just include an additional field called TAB_ID in your select query and sort using that field as below:
SELECT CHAR1 FROM
(
SELECT 'd' AS char1 , 2 AS sortcol, '1' AS TAB_ID FROM dual
UNION
SELECT 'c' AS char1 , 1 AS sortcol, '1' AS TAB_ID FROM dual
UNION
SELECT 'a' AS char1 , 1 AS sortcol, '2' AS TAB_ID FROM dual
UNION
SELECT 'b' AS char1 , 2 AS sortcol, '2' AS TAB_ID FROM dual
) ORDER BY TAB_ID, SORTCOL;
Check the result out from Working SQL Fiddle Here
To correct your original query and avoid the missing paranthesis error, use below query, but it does not seem to provide the right output:
select * from
(
SELECT * FROM
(
SELECT 'd' AS char1 , 2 AS sortcol FROM dual
UNION
SELECT 'c' AS char1 , 1 AS sortcol FROM dual
) Inner1
ORDER BY Inner1.sortcol
)
UNION
select * from
(
SELECT * FROM
(
SELECT 'a' AS char1 , 1 AS sortcol FROM dual
UNION
SELECT 'b' AS char1 , 2 AS sortcol FROM dual
) Inner2
ORDER BY Inner2.sortcol
) ;
来源:https://stackoverflow.com/questions/26295924/maintaining-the-order-by-in-union-of-two-ordered-by-queries