求查询Foo列顺序异常行ID的SQL语句(Id与Foo无间隙递增)
解决方案
针对你的需求,这里提供两种高效的SQL查询方法来找出Foo列顺序异常的行Id:
方法一:利用相邻行对比(通用型,适配多数现代SQL数据库)
这种方法通过窗口函数LAG()和LEAD()获取当前行的前后行Foo值,判断是否符合无间隙升序的规则:
SELECT Id FROM ( SELECT Id, Foo, LAG(Foo) OVER (ORDER BY Id) AS prev_foo, LEAD(Foo) OVER (ORDER BY Id) AS next_foo FROM your_table_name ) AS sub_query WHERE -- 首行:检查是否等于下一行Foo值减1 (prev_foo IS NULL AND Foo != next_foo - 1) -- 尾行:检查是否等于上一行Foo值加1 OR (next_foo IS NULL AND Foo != prev_foo + 1) -- 中间行:既不等于上一行+1,也不等于下一行-1 OR (prev_foo IS NOT NULL AND next_foo IS NOT NULL AND Foo != prev_foo + 1 AND Foo != next_foo - 1);
逻辑说明
LAG(Foo) OVER (ORDER BY Id):获取当前行的上一行Foo值LEAD(Foo) OVER (ORDER BY Id):获取当前行的下一行Foo值- 分首行、尾行、中间行三种场景判断异常,只要不符合连续升序规则的行都会被筛选出来
方法二:利用序列固定关系(更简洁,依赖初始值正确)
由于Id和Foo均为无间隙升序,正常情况下每一行的Foo值满足:Foo = 首行Foo值 + Id - 1,直接通过这个等式筛选异常行:
SELECT Id FROM your_table_name WHERE Foo != (SELECT Foo FROM your_table_name WHERE Id = 1) + Id - 1;
逻辑说明
- 先查询Id=1的Foo值作为基准值
- 计算每一行的预期Foo值,与实际值对比,不相等的即为异常行
示例验证
针对你给出的异常表:
| Id | Foo |
|---|---|
| 1 | 12 |
| 2 | 13 |
| 3 | 15 |
| 4 | 14 |
| 5 | 16 |
两种方法都会返回结果:3和4,符合需求。
内容的提问来源于stack exchange,提问作者yesman
相关产品推荐
相关产品推荐

