Maintaining the order by in union of two ordered by queries

为君一笑 提交于 2019-12-12 04:46:44

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!