[英]Get list of year ranges from list of years?
Is it possible to get a list of year ranges from a list of years? 是否可以从年份列表中获得年份范围列表?
Say there is a table like 说有一张桌子
Year
1990
1991
1992
1999
2001
2002
2015
Or like 或喜欢
Years
1990,1991,1992,1999,2001,2002,2015
I am not sure where to start; 我不确定从哪里开始。 how can one get the ranges within those years?
在那几年内如何获得范围? eg
例如
1990-1992,1999,2001-2002,2015
Here is example: 这是示例:
SELECT *
INTO #years
FROM (VALUES
(1990),
(1991),
(1992),
(1999),
(2001),
(2002),
(2015)) AS D(Year)
SELECT STUFF((
SELECT ',' +
CASE
WHEN MIN(Year) = MAX(Year) THEN CAST(MIN(Year) AS VARCHAR(9))
WHEN MIN(Year) <> MAX(Year) THEN CAST(MIN(Year) AS VARCHAR(4)) + '-' +CAST(MAX(Year) AS VARCHAR(4))
END AS [text()]
FROM (
SELECT Year
,Year-ROW_NUMBER() OVER (ORDER BY Year) AS rowID
FROM #years) a
GROUP BY rowID
FOR XML PATH('')
),1,1,'');
The main idea is to find so called islands, which in this case is easy made by using ROW_NUMBER
in this select: 主要思想是找到所谓的孤岛,在这种情况下,通过在此选择中使用
ROW_NUMBER
可以轻松实现:
SELECT Year ,Year-ROW_NUMBER() OVER (ORDER BY Year)
Years will be subtracted from row numbers, which will mark same "islands". 行号将减去年份,这将标记相同的“岛”。 Meaning, if every next year are increasing by one as row number does, we will get same result number:
意思是,如果明年每隔行数增加一,我们将得到相同的结果数:
YEAR RowNR RESULT
1999 1 1998
2000 2 1998
2015 3 2012
This result numbers can be later used for grouping and getting MAX and MIN values. 此结果编号以后可用于分组和获取MAX和MIN值。
The technique to get actual ranges is known as islands and gaps . 获得实际范围的技术称为孤岛和间隙 。 And to get values aggregated in one row you can use different techniques, but here's simple one with accumulating data in the variable will work fine.
为了将值汇总成一行,您可以使用不同的技术,但这是在变量中累积数据的简单方法,可以很好地工作。
declare @temp table (y int)
declare @res nvarchar(max)
insert into @temp (y)
values
(1990),
(1991),
(1992),
(1999),
(2001),
(2002),
(2015)
;with cte_rn as (
select
row_number() over(order by y) as rn, y
from @temp
), cte_rng as (
select
case
when count(*) = 1 then cast(min(y) as nvarchar(max))
else cast(min(y) as nvarchar(max)) + '-' + cast(max(y) as nvarchar(max))
end as rng
from cte_rn
group by y - rn
)
select @res = isnull(@res + ', ', '') + rng
from cte_rng
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.