Sql ode>lag()开头。如果我理解正确:如果(当前值-上一个值)超出范围5,则为每个组分配一个新的groupid,然后根据类和groupid“分组”。这是最重要的intuitive@Yiping . . . 这标识了每个新组的起始位置(基于lag()。这是

Sql ode>lag()开头。如果我理解正确:如果(当前值-上一个值)超出范围5,则为每个组分配一个新的groupid,然后根据类和groupid“分组”。这是最重要的intuitive@Yiping . . . 这标识了每个新组的起始位置(基于lag()。这是,sql,sql-server,group-by,subquery,gaps-and-islands,Sql,Sql Server,Group By,Subquery,Gaps And Islands,ode>lag()开头。如果我理解正确:如果(当前值-上一个值)超出范围5,则为每个组分配一个新的groupid,然后根据类和groupid“分组”。这是最重要的intuitive@Yiping . . . 这标识了每个新组的起始位置(基于lag()。这是一个0或1的标志。然后它进行累积和,因此一个组中的所有内容都具有相同的组值。这是正确的。(除了我们必须将底部的所有m2.class更改为m3、m4、m5)。谢谢!@Yiping,很好的回答。我修正了我的答案以更正别名。很抱歉,我发现这不正确。。


ode>lag()开头。如果我理解正确:如果(当前值-上一个值)超出范围5,则为每个组分配一个新的groupid,然后根据类和groupid“分组”。这是最重要的intuitive@Yiping . . . 这标识了每个新组的起始位置(基于
lag()
。这是一个0或1的标志。然后它进行累积和,因此一个组中的所有内容都具有相同的组值。这是正确的。(除了我们必须将底部的所有m2.class更改为m3、m4、m5)。谢谢!@Yiping,很好的回答。我修正了我的答案以更正别名。很抱歉,我发现这不正确。。这尝试按>=5或<5分组,但我的请求是按接近的值分组。[3,5,7],[13,13,14],[25,27,31,35]。@Yiping奇怪的是,我使用CTE使其更具可读性:)。无论如何,我已经对它进行了编辑,添加了一个替代方法。
Class| Value
-------------
A    | 1
A    | 2
A    | 3
A    | 10
B    | 1
Class| ValueMin | ValueMax
---------------------------
A    | 1     |   3
A    | 10    |   10
B    | 1     |   1
select class, min(value) as minvalue, max(value) as maxvalue
from (select class, value,
             sum(IsNewGroup) over (partition by class order by value) as GroupId
      from (select class, value,
                   (case when lag(value) over (partition by class order by value) > value - 5
                         then 0 else 1
                    end) as IsNewGroup
            from t
           ) t
     ) t
group by class, groupid;
SELECT Under5.Class,
  (
    SELECT MIN(m2.Value) 
    FROM MyTable AS m2 
    WHERE m2.Value < 5 
      AND m2.Class = Under5.Class
  ) AS ValueMin,
  (
    SELECT MAX(m3.Value) 
    FROM MyTable AS m3 
    WHERE m3.Value < 5 
      AND m3.Class = Under5.Class
  ) AS ValueMax
FROM 
(
  SELECT DISTINCT m1.Class
  FROM MyTable AS m1 
  WHERE m1.Value < 5
) AS Under5
UNION
SELECT Over4.Class,
  (
    SELECT MIN(m4.Value) 
    FROM MyTable AS m4 
    WHERE m4.Value >= 5 
      AND m4.Class = Over4.Class
  ) AS ValueMin,
  (
    SELECT Max(m5.Value) 
    FROM MyTable AS m5 
    WHERE m5.Value >= 5 
      AND m5.Class = Over4.Class
  ) AS ValueMax
FROM 
(
  SELECT DISTINCT m6.Class
  FROM MyTable AS m6 
  WHERE m6.Value >= 5
) AS Over4
SELECT 
A.CLASS
,MIN(A.VALUE) AS MIN_VALUE
,MAX(A.VALUE) AS MAX_VALUE
FROM
     (SELECT 
      ROW_NUMBER()OVER(PARTITION BY CLASS ORDER BY VALUE) AS ROW_ID
      ,CLASS
      ,VALUE
      FROM SD_TEST) AS A
LEFT JOIN 
     (SELECT 
       ROW_NUMBER()OVER(PARTITION BY CLASS ORDER BY VALUE) AS ROW_ID
      ,CLASS
      ,VALUE
     FROM SD_TEST) AS B
ON A.CLASS = B.CLASS AND A.ROW_ID=B.ROW_ID+1
GROUP BY A.CLASS,CASE WHEN ABS(COALESCE(B.VALUE,0)-A.VALUE)<5 THEN 1 ELSE 0 END
ORDER BY A.CLASS,cASE WHEN ABS(COALESCE(B.VALUE,0)-A.VALUE)<5 THEN 1 ELSE 0 END DESC
if object_id('tempdb..#temp') is not null drop table #temp

create table #temp (class char(1),Value int);

insert into #temp values ('A',1);
insert into #temp values ('A',2);
insert into #temp values ('A',3);
insert into #temp values ('A',10);
insert into #temp values ('A',13);
insert into #temp values ('A',14);
insert into #temp values ('b',7);
insert into #temp values ('b',8);
insert into #temp values ('b',9);
insert into #temp values ('b',12);
insert into #temp values ('b',22);
insert into #temp values ('b',26);
insert into #temp values ('b',67);
with cte as
(select  distinct class,value,ROW_NUMBER() over ( partition by class order by value ) as R from #temp),
cte2 as
(
    select 
        c1.class
        ,c1.value
        ,c2.R as PreviousRec
        ,c3.r as NextRec
    from 
        cte c1
        left join cte c2 on (c1.class = c2.class and c1.R= c2.R+1 and c1.Value < c2.value + 5)
        left join cte c3 on (c1.class = c3.class and c1.R= c3.R-1 and c1.Value > c3.value - 5)
)

select
    Starts.Class
    ,Starts.Value as StartValue
    ,Ends.Value as EndValue
from
    (
     select 
        class
        ,value
        ,row_number() over ( partition by class order by value ) as GroupNumber
    from cte2
        where PreviousRec is null) as Starts join
    (
     select 
        class
        ,value
        ,row_number() over ( partition by class order by value ) as GroupNumber
    from cte2
        where NextRec is null) as Ends on starts.class=ends.class and starts.GroupNumber = ends.GroupNumber
select
        Starts.Class
        ,Starts.Value as StartValue
        ,Ends.Value as EndValue            
from
    (
        select class,Value ,row_number() over ( partition by class order by value ) as GroupNumber
        from
            (select distinct class,value from #temp) as T
        where not exists (select 1 from #temp where class=t.class and Value < t.Value and Value > t.Value -5 )
    ) Starts join
    (
        select class,Value ,row_number() over ( partition by class order by value ) as GroupNumber
        from
            (select distinct class,value from #temp) as T
        where not exists (select 1 from #temp where class=t.class and Value > t.Value and Value < t.Value +5 )
    ) ends on starts.class=ends.class and starts.GroupNumber = ends.GroupNumber