ChatGPT解决这个技术问题 Extra ChatGPT

如何在 SQL 中使用 union 排序?

当数据来自多个选择并将其合并在一起时,是否可以订购?如

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

如何按名称订购此查询?

我试过这个

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

但这不起作用。

如果您在联合查询中有相同的列,那么最后按您的列名排序。

b
bernd_k

写吧

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

order by 应用于完整的结果集


如果我希望仅将排序应用于 UNION 的顶部怎么办?
@marifrahman 看到我的回答stackoverflow.com/a/43855496/2340825
@marifrahman 抱歉挖掘了一个老话题,但它可能对其他人有所帮助。如果您希望将 ORDER BY 应用于 UNION 的第一部分,请用括号保护此 SELECT。
如果您不想返回 name 怎么办?您能否为 ORDER BY 提供两个表的别名,但从结果集中省略它?
M
Mark Robinson
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

正如 bernd_k 指出的那样,根据定义,组成 UNION 的各个 SELECT 不允许包含 ORDER BY 子句。唯一允许的 ORDER BY 子句位于 UNION 的末尾,它适用于整个 UNION,使得 xxx UNION yyy ORDER BY zzz 等同于 (xxx UNION yyy) ORDER BY zzz
n
nik7

为了使排序仅适用于 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%"

或者(针对 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

是的。这对子选择的结果进行排序。这不会对引用该子选择的 select 语句的结果进行排序。根据 SQL 标准,结果的顺序是未定义的,除非有明确的 order by 子句。您的示例中的第一个 select 可能按子选择返回的顺序返回其结果,但不能保证。此外,*not* 保证整个 union 的结果集的排序(标准中的相同规则)。如果你依赖订单,你最终会被咬。
@Nicholas Carey - 当我最初使用 UNION 进行测试时,它的行为如您所描述的那样不可预测,我认为 UNION ALL(至少在 Oracle 中)对于在底部上方订购顶部 SELECT 是必要的。但是,我提供了一个替代方案,它可以保证正确的排序并且应该是独立于数据库的。
不为我工作。使用 UNION ALL 的那个仍然无法维持第一个 SELECT 内的顺序。
第二个查询的问题是,它没有消除重复记录。因为您添加了另一列“rowOrder”,该列可能对重复记录具有不同的值。 UNION 针对 UNION ALL 的目的丢失了。
@AmitChigadani 消除重复不是原始问题的一部分,但可以修改 WHERE 子句以确保唯一性。例如:其中 Name like "%a%" AND age >= 15
C
Conrad37

正如其他答案所述,last UNION 之后的 ORDER BY 应适用于通过联合连接的两个数据集。

我有两个数据集使用不同的表但相同的列。最后一个 UNION 之后的 ORDER BY 仍然无效。

ORDER BY 子句中使用的列使用别名就可以了。

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

解决方案是使用别名 User_Name,如下所示:

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

不要在 spark SQL 中使用技巧:mismatched input 'FOR' expecting <EOF>
也许错误输入,应该来自,而不是,在两个例子的第一行?
这是对我帮助最大的答案,因为我在查询中使用了别名,但随后尝试按原始列名排序。它在 UNION 的两个部分中是相同的列名,但是因为我用别名命名了它,所以它正在寻找我使用过的特定别名。所以只是对其他人的警告:如果您在 UNION 中使用别名并希望按该列排序,请确保您按别名排序。
m
moonvader

其他两个答案都是正确的,但我认为值得注意的是,我被卡住的地方没有意识到您需要按别名排序并确保两个选择的别名相同......所以

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

请注意,我在第一个选择中使用单引号,而在其他选择中使用反引号。

这将为您提供所需的排序。


您想在第一个选择中使用单引号并在其他选择中使用反引号有什么重要意义?理想情况下,它应该是一致的。
第一个选择是文字;它是一个像“NAMES”这样的标题。第二个选择是对表的引用。因此,您的第一行将显示“NAMES”,其余行将是从表中选择的实际名称。关键是您的标题很可能与您从中选择的列的名称是相同的字符串,这是使用您想要的标签而不会在您的联合中发生冲突的解决方案。
经过一些实验,我发现 ORDER BY 子句中提到的别名必须在 SELECT 子句中提到。您不能按另一列排序。当然,如果您真的想避免返回额外的列,您可以通过将整个内容包装在 SELECT a, b, c FROM (<insert union query here>) AS x; 中来解决这个问题。
S
SvenBM

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

n
nik7

如果我希望排序仅应用于 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
)

E
Edward

为了添加到一个旧主题,我使用了 ROW_NUMBER(使用 MS SQL)。这允许在 UNION 中进行排序(排序)。因此,使用来自 @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

因此,调整或省略您想要排序的内容,并根据需要添加降序。


请将代码和数据添加为文本 (using code formatting),而不是图像。图片:A)不允许我们复制和粘贴代码/错误/数据以进行测试; B) 不允许根据代码/错误/数据内容进行搜索;和many more reasons。除了代码格式的文本之外,只有在图像添加了一些重要的东西,而不仅仅是文本代码/错误/数据传达的内容时,才应该使用图像。
Ω
ΩmegaMan

向查询中添加一列,该列可以子标识要对其进行排序的数据。

在下面的示例中,我使用了一个 Common Table Expression 和 选择您显示的内容,并将它们放入 CTE 上的特定组中;然后将这两个组中的 union 放入 AllStudents

然后,最终选择将首先对 SortIndex 列进行 AllStudents 排序,然后然后按 name 进行排序,例如:

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;

总而言之,它将首先按组排序所有学生,然后按组内的名称进行子排序。


K
Koushik Roy

要将 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);


与 PostgreSQL 一起使用
A
Ahmad Aghazadeh

可以使用这个:

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

F
Fandango68

为什么不使用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

TOP 2000000 是一个任意数字,足以捕获所有数据。根据您的要求进行调整。


“前100%”更好。
“前 100%”存在问题。见上面的链接
有趣。链接在哪里?
嗯,似乎有人删除了他们的评论。好的:stackoverflow.com/questions/1393508/… 和这里 sqlshack.com/… 这完全与性能有关,具体取决于索引。