Sql 按范围分组记录

Sql 按范围分组记录,sql,sql-server,gaps-and-islands,Sql,Sql Server,Gaps And Islands,我有一组具有相同值的“跟随”行,我想将它们组合在一起,形成“从”和“到”。建议的解决方案通常是使用ROW\u NUMBER()然后分组,但我发现有些情况不起作用,通过一个例子可以更好地理解: WITH CTE AS (SELECT * FROM (VALUES ('A', 37, ''), ('A', 38, ''), ('A', 39, ''), ('A', 40, '

我有一组具有相同值的“跟随”行,我想将它们组合在一起,形成“从”和“到”。建议的解决方案通常是使用
ROW\u NUMBER()
然后分组,但我发现有些情况不起作用,通过一个例子可以更好地理解:

WITH
CTE AS
    (SELECT *
     FROM (VALUES ('A', 37, ''),
                  ('A', 38, ''),
                  ('A', 39, ''),
                  ('A', 40, ''),
                  ('A', 41, ''),
                  ('A', 42, ''),
                  ('A', 43, ''),
                  ('B', 44, '=> error Grupo 43'),
                  ('B', 45, '=> error Grupo 43'),
                  ('C', 46, ''),
                  ('C', 47, ''),
                  ('B', 48, ''),
                  ('B', 49, ''),
                  ('B', 50, ''),
                  ('A', 51, '=> error Grupo 43'),
                  ('A', 52, '=> error Grupo 43'),
                  ('A', 53, '=> error Grupo 43')) DATA (LETRA, DESDE, ERROR) )
SELECT *,
       ROW_NUMBER() OVER (PARTITION BY LETRA ORDER BY DESDE) AS rn,
       DESDE - ROW_NUMBER() OVER (PARTITION BY LETRA ORDER BY DESDE) AS Grupo
FROM CTE
ORDER BY SINCE;
有没有一种方法可以正确地“分组”记录


问候语

这是一个缺口和孤岛问题,您使用
DESDE-ROW_NUMBER()
进行的计算是正确的,但是您应该按照字母进一步分组,而不仅仅是这个剩余结果

WITH
CTE AS
    (SELECT *
     FROM (VALUES ('A', 37, ''),
                  ('A', 38, ''),
                  ('A', 39, ''),
                  ('A', 40, ''),
                  ('A', 41, ''),
                  ('A', 42, ''),
                  ('A', 43, ''),
                  ('B', 44, '=> error Grupo 43'),
                  ('B', 45, '=> error Grupo 43'),
                  ('C', 46, ''),
                  ('C', 47, ''),
                  ('B', 48, ''),
                  ('B', 49, ''),
                  ('B', 50, ''),
                  ('A', 51, '=> error Grupo 43'),
                  ('A', 52, '=> error Grupo 43'),
                  ('A', 53, '=> error Grupo 43')) DATA (LETRA, DESDE, ERROR))
,
Groups AS 
(
    SELECT
        C.*,
        GroupID = C.DESDE - ROW_NUMBER() OVER (PARTITION BY LETRA ORDER BY C.DESDE)
    FROM
        CTE AS C
)
SELECT
    C.LETRA,
    Desde = MIN(C.DESDE),
    Hasta = MAX(C.DESDE)
FROM
    Groups AS C
GROUP BY
    C.LETRA,
    C.GroupID
结果:

LETRA   Desde   Hasta
A       37      43
A       51      53
B       44      45
B       48      50
C       46      47

这是一个缺口和孤岛问题,您使用
DESDE-ROW_NUMBER()
进行的演算是正确的,但是您应该按照字母进一步分组,而不仅仅是这个rest结果

WITH
CTE AS
    (SELECT *
     FROM (VALUES ('A', 37, ''),
                  ('A', 38, ''),
                  ('A', 39, ''),
                  ('A', 40, ''),
                  ('A', 41, ''),
                  ('A', 42, ''),
                  ('A', 43, ''),
                  ('B', 44, '=> error Grupo 43'),
                  ('B', 45, '=> error Grupo 43'),
                  ('C', 46, ''),
                  ('C', 47, ''),
                  ('B', 48, ''),
                  ('B', 49, ''),
                  ('B', 50, ''),
                  ('A', 51, '=> error Grupo 43'),
                  ('A', 52, '=> error Grupo 43'),
                  ('A', 53, '=> error Grupo 43')) DATA (LETRA, DESDE, ERROR))
,
Groups AS 
(
    SELECT
        C.*,
        GroupID = C.DESDE - ROW_NUMBER() OVER (PARTITION BY LETRA ORDER BY C.DESDE)
    FROM
        CTE AS C
)
SELECT
    C.LETRA,
    Desde = MIN(C.DESDE),
    Hasta = MAX(C.DESDE)
FROM
    Groups AS C
GROUP BY
    C.LETRA,
    C.GroupID
结果:

LETRA   Desde   Hasta
A       37      43
A       51      53
B       44      45
B       48      50
C       46      47

如果使用聚合,则代码应该可以工作:

SELECT MIN(DESDE), MAX(DESDE), ERROR
FROM (SELECT CTE.*,
             ROW_NUMBER() OVER (PARTITION BY LETRA ORDER BY DESDE) AS rn,
             DESDE - ROW_NUMBER() OVER (PARTITION BY LETRA ORDER BY DESDE) AS Grupo
      FROM CTE
     ) x
GROUP BY Grupo, ERROR;

如果使用聚合,则代码应该可以工作:

SELECT MIN(DESDE), MAX(DESDE), ERROR
FROM (SELECT CTE.*,
             ROW_NUMBER() OVER (PARTITION BY LETRA ORDER BY DESDE) AS rn,
             DESDE - ROW_NUMBER() OVER (PARTITION BY LETRA ORDER BY DESDE) AS Grupo
      FROM CTE
     ) x
GROUP BY Grupo, ERROR;

你期望的结果是什么?(请注意,
是一个语句终止符,而不是“起始符”)。顺便问一下,您期望的结果集是什么?(P.s.
是语句终止符,而不是“起始符”)。顺便说一句