Sql UNION 合并多个结果集并排序

SQL表合并实践
1.建表语句及测试数据:
--创建表A
CREATE TABLE A(
	A1 int NULL,
	A2 nvArchAr(50) NULL,
	A3 decimAl(18, 0) NULL
) 
--测试数据
INSERT INTO A VALUES (1,'A1',1)
INSERT INTO A VALUES (2,'A2',1)
INSERT INTO A VALUES (3,'A3',1) 

--创建表B
CREATE TABLE B(
	B1 int NULL,
	B2 nvArchAr(50) NULL,
	B3 decimAl(18, 0) NULL
) 
--测试数据
INSERT INTO B VALUES (1,'B1',1)
INSERT INTO B VALUES (2,'B2',1)
INSERT INTO B VALUES (3,'B3',1)
INSERT INTO B VALUES (4,'B4',1)
INSERT INTO B VALUES (5,'B5',1)

2.数据预览:

A表:


B表:


3.合并数据集:

SELECT ROW_NUMBER() OVER(ORDER BY a) ROW_NUM,
       *
FROM   (
	       --结果集1
           (
               SELECT A1 AS a,
                      A2 AS b,
                      A3 AS c
               FROM   A
           )
           UNION
           --结果集2
           (
               SELECT B1 AS a,
                      B2 AS b,
                      B3 AS c
               FROM   B
           )
       )temp



<think>好的,用户现在想了解如何对使用UNION操作后的结果进行排序。这个问题我之前在回答中已经提到过几种方案,但需要结合用户提供的引用内容来更详细地解释。首先,我需要确认用户的问题场景:他们可能在合并两个或多个查询结果后,需要整体的排序,而不仅仅是各个子查询的排序。根据引用[2]和[3],用户可能遇到了在UNION使用ORDER BY无效的问题,或者需要多字段排序的情况。 用户提供的引用显示,直接在子查询中使用ORDER BY可能因为优先级问题无法生效,正确的做法是在整个UNION之后使用ORDER BY。此外,引用[3]提到了多字段排序,当主排序字段相同时,按次字段排序。这可能也是用户的需求之一。 接下来,我需要整理出几种不同的排序方法,包括基本排序、保持子顺序的整体排序、多字段排序以及分优先级排序。同时,还要考虑性能优化,比如使用临时表或索引来加速排序过程。此外,用户可能需要了解如何处理大数据量下的排序问题,例如分页或使用窗口函数。 需要注意的是,用户可能对UNIONUNION ALL的区别不太清楚,尤其是在去重和性能方面的影响。在排序时,是否需要去重可能会影响方法的选择。例如,使用UNION会去除重复行,但可能增加处理时间,而UNION ALL保留所有结果,效率更高。 另外,用户的问题中提到了引用[2]中的例子,其中在UNION ALL后直接加ORDER BY无效,正确的方法是将整个UNION结果作为子查询,然后在外层进行排序。这一点需要详细说明,确保用户理解执行顺序的重要性。 最后,可能需要提醒用户注意数据类型的一致性,因为UNION要求各子查询的列数和数据类型匹配,否则会导致错误。同时,性能优化部分可以建议使用索引或分页处理,特别是在处理大数据时,避免全表扫描和内存溢出。</think>根据SQLUNION操作的特性及排序需求,以下是5种专业级排序方案及详细技术解析: ### 一、基础全局排序(推荐) ```sql SELECT id, username, mobile, time FROM ( SELECT id, username, mobile, time FROM grouporder_leader WHERE courseid = 21 UNION ALL SELECT leadorderid, username, mobile, time FROM grouporder_partner WHERE courseid = 21 ) combined ORDER BY time DESC -- 全局排序字段 ``` **技术要点**: 1. 必须将UNION结果作为子查询 2. 外层ORDER BY作用于最终合并结果 3. 性能最佳方案(减少中间结果大小)[^2] ### 二、保持子顺序的排序 ```sql SELECT *, 1 as source_order FROM ( SELECT id, username, mobile, time FROM grouporder_leader WHERE courseid = 21 ORDER BY time DESC -- 子查询排序 ) t1 UNION ALL SELECT *, 2 as source_order FROM ( SELECT leadorderid, username, mobile, time FROM grouporder_partner WHERE courseid = 21 ORDER BY time DESC -- 子查询排序 ) t2 ORDER BY source_order, time DESC -- 优先按数据源排序 ``` **特殊场景**: - 需要保持原始子内部顺序 - 明确区分不同数据源位置[^2] ### 三、多字段混合排序 ```sql SELECT * FROM ( SELECT id, username, mobile, time, 'leader' type FROM grouporder_leader WHERE courseid = 21 UNION ALL SELECT leadorderid, username, mobile, time, 'partner' type FROM grouporder_partner WHERE courseid = 21 ) combined ORDER BY type DESC, -- 第一排序字段 time DESC, -- 第二排序字段 id ASC -- 第三排序字段 ``` **排序规则**: 1. 类型倒序(leader在前) 2. 时间倒序(最新在前) 3. ID正序(数值小的在前)[^3] ### 四、分优先级排序 ```sql SELECT * FROM ( SELECT id, username, 1 as priority FROM grouporder_leader WHERE courseid = 21 UNION ALL SELECT leadorderid, username, 2 as priority FROM grouporder_partner WHERE courseid = 21 ) tmp ORDER BY priority, username ``` **适用场景**: - 需要不同数据有不同排序权重 - 实现类似"置顶"效果 ### 五、窗口函数排序SQL Server/Oracle) ```sql SELECT ROW_NUMBER() OVER(ORDER BY time DESC) as rank_num, * FROM ( SELECT id, time FROM grouporder_leader WHERE courseid = 21 UNION ALL SELECT leadorderid, time FROM grouporder_partner WHERE courseid = 21 ) combined ``` **高级功能**: - 生成带排名的结果 - 支持DENSE_RANK()/NTILE()等函数 ### 性能优化方案 1. **索引策略**: ```sql CREATE INDEX idx_leader_time ON grouporder_leader(time) CREATE INDEX idx_partner_time ON grouporder_partner(time) ``` 2. **分页优化**: ```sql SELECT * FROM ( SELECT ..., ROW_NUMBER() OVER(ORDER BY time DESC) rn FROM combined ) t WHERE rn BETWEEN 1001 AND 2000 ``` 3. **临时表加速**: ```sql SELECT * INTO #temp FROM combined CREATE CLUSTERED INDEX idx_temp ON #temp(time DESC) SELECT * FROM #temp ORDER BY time DESC ``` ### 易错点警示 1. **数据类型不一致**: ```sql -- 错误示例(varchar与int混用) SELECT 'text' col UNION SELECT 123 -- 正确转换 SELECT CONVERT(varchar(10), col) FROM table ``` 2. **隐式排序陷阱**: ```sql /* 错误认知:认为UNION会保持子查询顺序 实际执行计划可能打乱原始顺序 */ ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值