选择一组连续值中的最大值

时间:2014-07-05 16:06:43

标签: sql sqlite max

如何只检索只有连续值的组的最大值?

我有一个只有唯一值的电话数据库,我想只获得每个电话号码组TelNr的最高号码,我正在努力。

id     |      TeNr       |      Position
1      |      100        |     SLMO2.1.3
2      |      101        |     SLMO2.3.4
3      |      103        |     SLMO2.4.1
4      |      104        |     SLMO2.3.2
5      |      200        |     SLMO2.5.1
6      |      201        |     SLMO2.5.2
7      |      204        |     SLMO2.5.5
8      |      300        |     SLMO2.3.5
9      |      301        |     SLMO2.6.2
10     |      401        |     SLMO2.4.8

结果应该是:

TelNr
101
104
201
204
301
401

到目前为止,我已经尝试了几乎所有我能找到的小费,以及我是否收到所有TelNr或根本没有号码,这对我来说是无用的。

使用SQLITE运行此操作有什么好主意吗?

1 个答案:

答案 0 :(得分:1)

因此,您正在寻找差距,并希望获得这些差距的第一个值。

这可能是获取它们的最佳方法,尝试检查当前TeNr加1的行,如果没有,则找到它:

select t1.TeNr, t1.TeNr + 1 as unused_TeNr
from tab as t1
left join Tab as t2
on t2.TeNr = t1.TeNr + 1
where t2.TeNr is null

修改

要获取缺失值的范围,您需要使用一些旧式SQL,因为SQLite似乎不支持ROW_NUMBER等。

select
   TeNr + 1 as RangeStart, 
   nextTeNr - 1 as RangeEnd, 
   nextTeNr - TeNr - 1 as cnt
from
 (
   select TeNr, 
     ( select min(TeNr) from tab as t2
       where t2.TeNr > t1.TeNr ) as nextTeNr
   from tab as t1
 ) as dt
where nextTeNr > TeNr + 1

它可能效率不高,但如果行数很小和/或TeNr上有索引,则可能没问题。

如果你的SQLite版本支持递归查询,那么在结果集中将每个值作为一行获取是非常困难的:

with recursive cte (TeNr, missing, maxTeNr) as
 (
   select
      min(TeNr) as TeNr,   -- start of range of existing numbers
      0 as missing,        -- 0 = TeNr exists, 1 = TeNr is missing
      max(TeNr) as maxTeNr -- end of range of existing numbers
   from tab 

   union all

   select
      cte.TeNr + 1,        -- next TeNr, if it doesn't exists tab.TeNr will be NULL
      case when tab.TeNr is not null then 0 else 1 end, 
      maxTeNr
   from cte left join tab
   on tab.TeNr = cte.TeNr + 1
   where cte.TeNr + 1 < maxTeNr
  )  
select TeNr 
from cte
where missing = 1

根据您的数据,这可能会返回大量行。 您还可以使用先前RangeStart / RangeEnd查询的结果作为此递归的输入。