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