如何按work_contract各选一条实例?UNION结合LIMIT失效求解
按work_contract分组各取一条数据的解决方法
你原来的代码无法运行,是因为UNION拼接的每个子查询没有用括号包裹,数据库会把LIMIT识别为对整个UNION结果的限制,而非单个子查询的限制。下面是几种可行的实现方式:
方法一:给每个子查询加括号(最直接适配你的需求)
给每个带LIMIT的SELECT语句套上括号,就能让LIMIT作用于单个子查询,再用UNION ALL拼接结果(因为不同contract的记录不会重复,用UNION ALL比UNION DISTINCT效率更高):
(SELECT * FROM table1 WHERE work_contract = "SECONDMENT" LIMIT 1) UNION ALL (SELECT * FROM table1 WHERE work_contract = "INTER" LIMIT 1) UNION ALL (SELECT * FROM table1 WHERE work_contract = "CASUAL" LIMIT 1)
方法二:用窗口函数(更灵活,适合多分组场景)
如果你的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server等),可以用ROW_NUMBER()按work_contract分组,每组取第一条:
SELECT * FROM ( SELECT *, -- 按work_contract分组,每组内可以按你需要的字段排序(比如id、创建时间) ROW_NUMBER() OVER (PARTITION BY work_contract ORDER BY id) AS rn FROM table1 WHERE work_contract IN ("SECONDMENT", "INTER", "CASUAL") ) t WHERE rn = 1;
这里的ORDER BY id可以换成你需要的排序规则,比如取最新的记录就按create_time DESC排序。
方法三:适配低版本数据库(无窗口函数时)
如果你的数据库不支持窗口函数(比如MySQL 5.x),可以通过分组取唯一标识(比如主键)的方式实现:
SELECT t1.* FROM table1 t1 JOIN ( -- 每个work_contract组取最小的id,也可以用MAX(id)取最大的 SELECT work_contract, MIN(id) AS target_id FROM table1 WHERE work_contract IN ("SECONDMENT", "INTER", "CASUAL") GROUP BY work_contract ) t2 ON t1.id = t2.target_id;
内容的提问来源于stack exchange,提问作者Anshu Kumar
相关产品推荐
相关产品推荐

