Как сгруппировать ранжированные значения с помощью SQL Server

StackOverflow https://stackoverflow.com/questions/472732

Вопрос

У меня есть такая таблица значений

978412, 400
978813, 20
978834, 50
981001, 20

Как видно, второе число при добавлении к первому - это 1 число перед следующим в последовательности. Последнее число не находится в диапазоне (не соответствует прямой последовательности, как в следующем значении). Что мне нужно, это CTE (да, в идеале), который будет выводить это

978412, 472
981001, 20

Первая строка содержит начальный номер диапазона, а затем сумму узлов внутри. Следующая строка - это следующий диапазон, который в этом примере совпадает с исходными данными.

Это было полезно?

Решение

Из статьи, которую опубликовал Джош, вот мое мнение (проверено и работает):

SELECT
    MAX(t1.gapID) as gapID,
    t2.gapID-MAX(t1.gapID)+t2.gapSize as gapSize
    -- max(t1) is the specific lower bound of t2 because of the group by.
FROM
  ( -- t1 is the lower boundary of an island.
    SELECT gapID
    FROM gaps tbl1 
    WHERE
      NOT EXISTS(
        SELECT *
        FROM gaps tbl2 
        WHERE tbl1.gapID = tbl2.gapID + tbl2.gapSize + 1
      )
  ) t1
  INNER JOIN ( -- t2 is the upper boundary of an island.
    SELECT gapID, gapSize
    FROM gaps tbl1 
    WHERE
      NOT EXISTS(
        SELECT * FROM gaps tbl2 
        WHERE tbl2.gapID = tbl1.gapID + tbl1.gapSize + 1
      )
  ) t2 ON t1.gapID <= t2.gapID -- For all t1, we get all bigger t2 and opposite.
GROUP BY t2.gapID, t2.gapSize

Другие советы

Ознакомьтесь с этой статьей MSDN . Он дает вам решение вашей проблемы, если он будет работать для вас, зависит от количества имеющихся у вас данных и ваших требований к производительности для запроса.

Изменить:

Хорошо, используя пример в запросе, и применив его последнее решение ко второму способу получения островков (первый способ привел к ошибке в SQL 2005).

SELECT MIN(start) AS  startGroup, endGroup, (endgroup-min(start) +1) as NumNodes
FROM (SELECT g1.gapID AS start,
(SELECT min(g2.gapID) FROM #gaps g2 
WHERE g2.gapID >= g1.gapID and NOT EXISTS
(SELECT * FROM #gaps g3 
WHERE g3.gapID - g2.gapID = 1)) as endGroup
FROM #gaps g1) T1 GROUP BY endGroup

Я добавил (endgroup-min(start) +1) as NumNodes. Это даст вам счет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top