SQL需求:基于Type返回Top3唯一且未返回过的员工ID行
解决思路与SQL实现
你的问题核心在于两个SELECT TOP 3查询是独立执行的,没有共享已选中的employee_id集合,所以会出现重复ID。我们可以通过先预存type=1的前3个唯一ID,再在type=2的查询中排除这些ID来实现需求。
具体SQL方案
这里用CTE(公共表表达式)先提取type=1的前3个唯一employee_id,再分别查询type=1的目标行和type=2中未被选中的行,最后合并结果:
-- 定义CTE存储type=1的前3个唯一employee_id WITH type1_selected AS ( SELECT DISTINCT employee_id FROM your_table -- 替换成你的实际表名 WHERE type = 1 ORDER BY employee_id -- 按ID排序保证取前3的一致性,可根据需求调整排序规则 LIMIT 3; -- 注意:SQL Server用TOP 3,Oracle用FETCH FIRST 3 ROWS ONLY,根据你的数据库调整 ) -- 先获取type=1的前3行 SELECT employee_id, date, type, eligible FROM your_table WHERE type = 1 AND employee_id IN (SELECT employee_id FROM type1_selected) UNION ALL -- 再获取type=2中不在type1_selected里的前3行 SELECT employee_id, date, type, eligible FROM your_table WHERE type = 2 AND employee_id NOT IN (SELECT employee_id FROM type1_selected) ORDER BY type, employee_id; -- 按type和ID排序,和期望结果一致
方案说明
- CTE的作用:
type1_selected会先查询出type=1的前3个唯一employee_id,作为后续查询的排除依据,确保type=2的结果不会重复出现这些ID。 - UNION ALL vs UNION:这里用
UNION ALL更高效,因为我们已经通过逻辑确保两个查询结果不会有重复ID,不需要额外的去重操作。 - 排序规则:
ORDER BY employee_id保证取前3的ID是固定的(比如1、2、3),如果你的需求是按其他规则选前3(比如日期),可以修改排序条件。
针对你的测试数据,这个查询会先返回type=1的1、2、3号员工行,再返回type=2的4、5、6号员工行,完全符合你期望的结果。
内容的提问来源于stack exchange,提问作者RazorKillBen
相关产品推荐
相关产品推荐

