如何获得具有连续但不连续的ID的表的均匀分割的段的最小值/最大值

时间:2017-03-15 11:57:11

标签: sql sql-server

假设我有一个包含10米行的表。 我想把它除以6 然后获取一个列的最小值和最大值(在这种情况下,特别是在这种情况下为Id),然后表示类似的东西

segment1 start: 1
segment1 finish:  10

segment2 start: 100001
segment2 finish: 2000000

.....
segment6 start: 9000001
segment6 end: 10000000

使用MSSQL。

我不需要格式化,无论如何我只需要数字。

2 个答案:

答案 0 :(得分:2)

因为我没有看到这些段是预定义的,所以这可能是一个解决方案。希望你能用这个做点什么。

DECLARE @T TABLE (Number INT)
DECLARE @I INT
SET @I = 1

WHILE @I <= 100000
BEGIN
    INSERT INTO @T VALUES(@I)
    SET @I = @I + 1
END

SELECT 'Segment: ' + CAST(Segment AS VARCHAR(5)) AS Segment, 
    MIN(Number) AS StartSegment, MAX(Number) AS EndSegment
FROM   (SELECT t.Number, NTILE(6) OVER (ORDER BY t.Number) AS Segment
        FROM @T AS t) AS a
GROUP BY a.Segment

结果

+-----------+-------------+-----------+
|Segment    |StartSegment |EndSegment |
+-----------+-------------+-----------+
|Segment: 1 |1            |16667      |
|Segment: 2 |16668        |33334      |
|Segment: 3 |33335        |50001      |
|Segment: 4 |50002        |66668      |
|Segment: 5 |66669        |83334      |
|Segment: 6 |83335        |100000     |
+-----------+-------------+-----------+

答案 1 :(得分:0)

WITH t (id) AS (
          SELECT        1
UNION ALL SELECT       10

UNION ALL SELECT   100001
UNION ALL SELECT  2000000

UNION ALL SELECT  3000000
UNION ALL SELECT  4000000

UNION ALL SELECT  5000000
UNION ALL SELECT  6000000

UNION ALL SELECT  7000000
UNION ALL SELECT  8000000

UNION ALL SELECT  9000001
UNION ALL SELECT 10000000
), rn AS (
    SELECT *, ROW_NUMBER() OVER (ORDER BY id) As _rn
    FROM t
), mx (         _rn,       /* number of chunks to split into */ _tgt) AS (
    SELECT MAX(_rn), CASE WHEN MAX(_rn) < 6 THEN MAX(_rn) ELSE 6 END
    FROM rn
),  s (        _i,             _from,                              _to) AS (
    SELECT      2, CAST(1 As bigint), (SELECT _rn      / _tgt FROM mx)
    UNION ALL
    SELECT _i + 1,           _to + 1, (SELECT _rn * _i / _tgt FROM mx)
    FROM s WHERE _to < (SELECT _rn FROM mx)
    )
SELECT
    _i - 1                                As [segment],
    (SELECT id FROM rn WHERE _rn = _from) As [start],
    (SELECT id FROM rn WHERE _rn = _to  ) As [finish]
FROM s

NTile&#39; Kevin后使用answer(SQL Server 2012+):

WITH t (id) AS (
          SELECT        1
UNION ALL SELECT       10

UNION ALL SELECT   100001
UNION ALL SELECT  2000000

UNION ALL SELECT  3000000
UNION ALL SELECT  4000000

UNION ALL SELECT  5000000
UNION ALL SELECT  6000000

UNION ALL SELECT  7000000
UNION ALL SELECT  8000000

UNION ALL SELECT  9000001
UNION ALL SELECT 10000000
), c AS (
    SELECT *, NTILE(6) OVER(ORDER BY id) AS segment
    FROM t
)
SELECT         segment,
    MIN(id) As [start],
    MAX(id) As [finish]
FROM c
GROUP BY segment