7

我在 MySql 5 中有一个电话号码表。简单的结构是

Accounts
id varchar(32) NOT NULL

记录如下

27100070000
27100070001
27100070002
27100070003
27100070004
27100070005
27100070008
27100070009
27100070012
27100070015
27100070016
27100070043

我需要对这些数据进行排序,并将连续的数字块分组到数字范围内。我愿意在 C# LINQ 中实现该解决方案,但服务器端 MySql 是一等奖。MySql 中有没有办法汇总这些数据,以便输出如下?

Start       | End
-------------------------
27100070000 | 27100070005
27100070008 | 27100070009
27100070012 | 27100070015
27100070016 | NULL
27100070043 | NULL
4

1 回答 1

15

有一个简单的技巧可以将连续的条目折叠成一个组。如果按 (row_number - entry) 分组,则连续的条目将最终在同一组中。这是一个示例,说明我的意思:

查询

SELECT phonenum, @curRow := @curRow + 1 AS row_number, phonenum - @curRow
from phonenums p
join (SELECT @curRow := 0) r

结果

|    PHONENUM | ROW_NUMBER | PHONENUM - @CURROW |
-------------------------------------------------
| 27100070000 |          1 |        27100069999 |
| 27100070001 |          2 |        27100069999 |
| 27100070002 |          3 |        27100069999 |
| 27100070003 |          4 |        27100069999 |
| 27100070004 |          5 |        27100069999 |
| 27100070005 |          6 |        27100069999 |
| 27100070008 |          7 |        27100070001 |
| 27100070009 |          8 |        27100070001 |
| 27100070012 |          9 |        27100070003 |
| 27100070015 |         10 |        27100070005 |
| 27100070016 |         11 |        27100070005 |
| 27100070040 |         12 |        27100070028 |

请注意连续的条目如何具有相同的值PHONENUM - @CURROW。如果我们对该列进行分组,并选择每个组的最小值和最大值,您将获得摘要(有一个例外:如果需要,您可以将 END 值替换为NULLif START = END):

查询

select min(phonenum), max(phonenum) from
(
  SELECT phonenum, @curRow := @curRow + 1 AS row_number
  from phonenums p
  join (SELECT @curRow := 0) r
) p
group by phonenum - row_number

结果

| MIN(PHONENUM) | MAX(PHONENUM) |
---------------------------------
|   27100070000 |   27100070005 |
|   27100070008 |   27100070009 |
|   27100070012 |   27100070012 |
|   27100070015 |   27100070016 |
|   27100070040 |   27100070040 |

演示:http ://www.sqlfiddle.com/#!2/59b04/5

于 2012-11-19T15:45:07.303 回答