从SQL Server表获取连续数字范围

时间:2015-10-11 05:43:55

标签: sql sql-server

我正在使用SQL Server 2014。我有一个表BookNo列为datatype int。此列包含以下数据

|BookNo|
1
2
3
4
5
10
12
13
25
26
27
28

我想在Sql查询中使用连续数字范围。从上面的数据我的输出应该像

1 to 5
10 to 13
25 to 28

任何帮助......

3 个答案:

答案 0 :(得分:3)

我认为你可以使用这样的查询:

SELECT BookNo, ISNULL(LEAD(prev) OVER (ORDER BY BookNo) , (SELECT MAX(BookNo) FROM yourTable)) As toCon
FROM
    (
    SELECT *, LAG(BookNo) OVER (ORDER BY BookNo) prev, BookNo - LAG(BookNo) OVER (ORDER BY BookNo) diff
    FROM yourTable) dt
WHERE 
    (ISNULL(diff, 0) <> 1);

[SQL Fiddle Demo]

答案 1 :(得分:2)

另一种基于窗口化聚合函数的解决方案,它也运行在SS2014以下的版本上(并且应该比LAG / LEAD表现更好):

SELECT MIN(BookNo) AS BookNoFrom, MAX(BookNo) AS BookNoTo
FROM
  (
    SELECT BookNo, 
        BookNo - ROW_NUMBER() OVER (ORDER BY BookNo) AS dummy
    FROM yourTable
  ) dt
GROUP BY dummy

请参阅Fiddle

dummy计算基于以下事实:BookNoROW_NUMBER都是序号,但BookNo可能存在差距。对于连续的BookNo,差异总是相同的,当它增加的间隙时(dummy值没有实际意义,但它对于连续的行是相同的值)。

答案 2 :(得分:0)

假设您的表名是Books:

;with MainCTE as (
    /*Left Join to get the Last Continous number (Like 5,13,28)*/
    select c1.BookNo as lst, c1.BookNo as previous from Books c1 left join Books c2 on  c1.BookNo+1 = c2.BookNo 
    where c2.BookNo is null 
    /*Union all to make recusion and get the previous contionous number*/
    /*Note: i returned the lst number as it is. only i changed the previous number*/
        union all
            select MainCTE.lst,Books.BookNo from MainCTE inner join Books on MainCTE.previous = Books.BookNo+ 1
)
select min(previous),max(lst) from MainCTE
group by lst