如何从含employeeId、salary列的表中提取奇偶交替行(SQL实现)
嘿,这个需求其实挺普遍的——要提取数据表的奇数或偶数行,核心思路是先给每行生成一个有序的行号,再根据行号的奇偶性筛选。不过不同SQL数据库的实现细节有点区别,下面给你整理几种主流数据库的具体方案:
提取交替行(奇偶行)的SQL实现
首先得明确:SQL里的表本质是无序的集合,所以必须先指定排序规则生成行号,否则提取的“奇偶行”完全没有意义。下面的例子默认用employeeId作为排序依据,你可以根据业务需求换成其他字段(比如薪资、入职时间等)。
1. MySQL/MariaDB
如果是MySQL 8.0及以上版本,推荐用窗口函数;旧版本可以用用户变量来实现。
方法一:窗口函数(推荐)
-- 提取奇数行 SELECT employeeId, salary FROM ( SELECT employeeId, salary, ROW_NUMBER() OVER (ORDER BY employeeId) AS row_num -- 按employeeId排序生成行号,可替换成你需要的字段 FROM your_table_name -- 替换成你的表名 ) AS numbered_rows WHERE row_num % 2 = 1; -- 提取偶数行,只需要修改WHERE条件 SELECT employeeId, salary FROM ( SELECT employeeId, salary, ROW_NUMBER() OVER (ORDER BY employeeId) AS row_num FROM your_table_name ) AS numbered_rows WHERE row_num % 2 = 0;
方法二:旧版本MySQL(无窗口函数支持)
用用户变量手动生成行号:
-- 提取奇数行 SET @row_num = 0; SELECT employeeId, salary FROM ( SELECT employeeId, salary, @row_num := @row_num + 1 AS row_num FROM your_table_name ORDER BY employeeId ) AS numbered_rows WHERE row_num % 2 = 1;
2. PostgreSQL
PostgreSQL支持窗口函数,也可以用MOD函数来做取模判断:
-- 提取奇数行 SELECT employeeId, salary FROM ( SELECT employeeId, salary, ROW_NUMBER() OVER (ORDER BY employeeId) AS row_num FROM your_table_name ) AS numbered_rows WHERE MOD(row_num, 2) = 1; -- 提取偶数行 SELECT employeeId, salary FROM ( SELECT employeeId, salary, ROW_NUMBER() OVER (ORDER BY employeeId) AS row_num FROM your_table_name ) AS numbered_rows WHERE MOD(row_num, 2) = 0;
3. SQL Server
语法和MySQL类似,用ROW_NUMBER()生成行号后取模筛选:
-- 提取奇数行 SELECT employeeId, salary FROM ( SELECT employeeId, salary, ROW_NUMBER() OVER (ORDER BY employeeId) AS row_num FROM your_table_name ) AS numbered_rows WHERE row_num % 2 = 1; -- 提取偶数行 SELECT employeeId, salary FROM ( SELECT employeeId, salary, ROW_NUMBER() OVER (ORDER BY employeeId) AS row_num FROM your_table_name ) AS numbered_rows WHERE row_num % 2 = 0;
关键注意点
- 排序字段不能少:一定要在
ROW_NUMBER()的OVER子句里指定ORDER BY,否则行号是随机分配的,提取的奇偶行完全不符合预期。 - 特殊情况:自增主键:如果你的
employeeId是连续无间隙的自增主键,那可以直接用主键取模,省去子查询:
-- 直接提取奇数行(仅适用于employeeId连续无间隙的情况) SELECT employeeId, salary FROM your_table_name WHERE employeeId % 2 = 1;
但如果有数据删除导致ID不连续,这种方法就会出错,还是用行号的方案更可靠。
内容的提问来源于stack exchange,提问作者S Pavan kumar
相关产品推荐
相关产品推荐

