简体   繁体   English

如何在 SQL 中使用 union 排序?

[英]How to order by with union in SQL?

Is it possible to order when the data is come from many select and union it together?当数据来自多个选择并将其合并在一起时,是否可以订购? Such as

Select id,name,age
From Student
Where age < 15
Union
Select id,name,age
From Student
Where Name like "%a%"

How can I order this query by name?如何按名称订购此查询?

I tried this我试过这个

Select id,name,age
From Student
Where age < 15 or name like "%a%"
Order by name

But that does not work.但这不起作用。

Just write写吧

Select id,name,age
From Student
Where age < 15
Union
Select id,name,age
From Student
Where Name like "%a%"
Order by name

the order by is applied to the complete resultset order by 应用于完整的结果集

Select id,name,age
from
(
   Select id,name,age
   From Student
   Where age < 15
  Union
   Select id,name,age
   From Student
   Where Name like "%a%"
) results
order by name

In order to make the sort apply to only the first statement in the UNION , you can put it in a subselect with UNION ALL (both of these appear to be necessary in Oracle):为了使排序仅适用于UNION中的第一条语句,您可以将其放在带有UNION ALL的子选择中(这两个在 Oracle 中似乎都是必需的):

Select id,name,age FROM 
(    
 Select id,name,age
 From Student
 Where age < 15
 Order by name
)
UNION ALL
Select id,name,age
From Student
Where Name like "%a%"

Or (addressing Nicholas Carey's comment) you can guarantee the top SELECT is ordered and results appear above the bottom SELECT like this:或者(解决 Nicholas Carey 的评论)您可以保证顶部SELECT是有序的,并且结果显示在底部SELECT上方,如下所示:

Select id,name,age, 1 as rowOrder
From Student
Where age < 15
UNION
Select id,name,age, 2 as rowOrder
From Student
Where Name like "%a%"
Order by rowOrder, name

As other answers stated, ORDER BY after the last UNION should apply to both datasets joined by union.正如其他答案所述,最后一个UNION之后的ORDER BY应该适用于由联合连接的两个数据集。

I had two datasets using different tables but the same columns.我有两个数据集使用不同的表但相同的列。 ORDER BY after the last UNION still didn't work.最后一个UNION之后的ORDER BY仍然不起作用。

Using an alias for the column used in the ORDER BY clause did the trick.ORDER BY子句中使用的列使用别名就可以了。

SELECT Name, Address FROM Employee 
UNION
SELECT Customer_Name, Address FROM Customer
ORDER BY customer_name;   --Won't work

The solution was to use the alias User_Name , shown below:解决方案是使用别名User_Name ,如下所示:

SELECT Name AS User_Name, Address FROM Employee 
UNION
SELECT Customer_Name AS User_Name, Address FROM Customer
ORDER BY User_Name; 

Both other answers are correct, but I thought it worth noting that the place where I got stuck was not realizing that you'll need order by the alias and make sure that the alias is the same for both the selects... so其他两个答案都是正确的,但我认为值得注意的是,我被卡住的地方没有意识到您需要按别名排序并确保两个选择的别名相同......所以

select 'foo'
union
select item as `foo`
from myTable
order by `foo`

notice that I'm using single quotes in the first select but backticks for the others.请注意,我在第一个选择中使用单引号,而在其他选择中使用反引号。

That will get you the sorting you need.这将为您提供所需的排序。

Order By is applied after union , so just add an order by clause at the end of the statements: Order Byunion之后应用,所以只需在语句末尾添加一个order by子句:

Select id,name,age
From Student
Where age < 15
Union
Select id,name,age
From Student
Where Name like '%a%'
Order By name

If I want the sort to be applied to only one of the UNION if use UNION ALL :如果我希望排序仅应用于其中一个UNION如果使用UNION ALL

Select id,name,age
From Student
Where age < 15
Union all
Select id,name,age
From 
(
Select id,name,age
From Student
Where Name like "%a%"
Order by name
)

To add to an old topic, I used ROW_NUMBER (using MS SQL).为了添加到一个旧主题,我使用了 ROW_NUMBER(使用 MS SQL)。 This allows sorts (orders) within UNIONs.这允许在 UNION 中进行排序(排序)。 So using an idea from @BATabNabber to separate each half of the Union, and @Wodin of wrapping the whole thing in a select, I got:因此,使用@BATabNabber的想法来分隔联盟的每一半,以及将整个事物包装在一个选择中的@Wodin ,我得到:

Select Id, Name, Age from
(
Select Id, Name, Age, 1 as Mainsort
 , ROW_NUMBER() over (order by age) as RowNumber
From Student
Where Age < 15

Union

Select Id, Name, Age, 2 as Mainsort
 , ROW_NUMBER() over (Order by Name) as RowNumber
From Student
Where Name like '%a%'
) as x
Order by Mainsort, RowNumber

So adjust, or omit, what you want to Order by, and add Descendings as you see fit.因此,调整或省略您想要排序的内容,并根据需要添加降序。

Add a column to the query which can sub identify the data to sort on that.向查询中添加一列,该列可以子标识要对其进行排序的数据。

In the below example I use a Common Table Expression with the selects what you showed and places them into specific groups on the CTE;在下面的示例中,我使用 Common Table Expression 来选择您显示的内容并将它们放入 CTE 上的特定组中; then do a union off of both of those groups into AllStudents .然后AllStudents union

The final select will then sort AllStudents by the SortIndex column first and then by the name such as:最终的选择将首先SortIndex然后按nameAllStudents进行排序,例如:

WITH Juveniles as
(
      Select 1 as [SortIndex], id,name,age From Student
      Where age < 15
),

AStudents as
(
      Select 2 as [SortIndex], id,name,age From Student
      Where Name like "%a%" 
),

AllStudents as
(
      select * from Juveniles
      union 
      select * from AStudents
)

select * from AllStudents
sort by [SortIndex], name;

To summarize, it will get all the students which will be sorted by group first, and subsorted by the name within the group after that.总而言之,它将首先按组排序所有学生,然后按组内的名称进行子排序。

To apply an ORDER BY or LIMIT clause to an individual SELECT, parenthesize the SELECT and place the clause inside the parentheses:要将 ORDER BY 或 LIMIT 子句应用于单个 SELECT,请将 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);

Can use this:可以使用这个:

Select id,name,age
From Student
Where age < 15
Union ALL
SELECT * FROM (Select id,name,age
From Student
Where Name like "%a%")

Why not use TOP X?为什么不使用TOP X?

SELECT pass1.* FROM 
 (SELECT TOP 2000000 tblA.ID, tblA.CustomerName 
  FROM TABLE_A AS tblA ORDER BY 2) AS pass1
UNION ALL 
SELECT pass2.* FROM 
  (SELECT TOP 2000000 tblB.ID, tblB.CustomerName 
   FROM TABLE_B AS tblB ORDER BY 2) AS pass2

The TOP 2000000 is an arbitrary number, that is big enough to capture all of the data. TOP 2000000 是一个任意数字,足以捕获所有数据。 Adjust as per your requirements.根据您的要求进行调整。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM