在一定的时间间隔内,我很难找到第一次和最后一次约会.如果你看下面的图片,你可以看到3个不同的个人ID.间隔是指相同的PersonID具有连贯的FromDate和ToDate.如果以上行中的这两行具有相同的PersonID,则FromDate是ToDate之后的1天.行1是一个区间,行2-5是一个区间.我想要做的是添加两个额外的列,它们代表一个间隔中的第一个日期和最后一个日期.

enter image description here

The code below is my attempt. First I have created a table with data. Then I'm creating a CTE, "NextDates", with extra columns with the value in FromDate on the row below, and one column with that row's PersonId. Like this:
enter image description here

然后我要创建另一个CTE."行数".在这里,我试图用‘1’或一个递增的整数来标记时间间隔的每一端.这一步可能是完全不必要的?如果我可以在该间隔的每一行中获得相同的"RowNr",那么我应该能够对其进行分组,并找到最大和最小日期.

DROP TABLE IF EXISTS #ExampelTable
CREATE TABLE #ExampelTable (Id INT IDENTITY(1,1), PersonId INT, FromDate DATE, ToDate DATE)

INSERT INTO #ExampelTable (PersonId,FromDate,ToDate) VALUES (10, '2009-01-01','2009-06-30')
INSERT INTO #ExampelTable (PersonId,FromDate,ToDate) VALUES (10, '2010-01-26','2010-01-31')
INSERT INTO #ExampelTable (PersonId,FromDate,ToDate) VALUES (10, '2010-02-01','2010-06-20')
INSERT INTO #ExampelTable (PersonId,FromDate,ToDate) VALUES (10, '2010-06-21','2011-02-17')
INSERT INTO #ExampelTable (PersonId,FromDate,ToDate) VALUES (10, '2011-02-18','2011-07-31')
INSERT INTO #ExampelTable (PersonId,FromDate,ToDate) VALUES (10, '2013-12-03','2014-06-30')
INSERT INTO #ExampelTable (PersonId,FromDate,ToDate) VALUES (10, '2015-11-03','2016-06-30')
INSERT INTO #ExampelTable (PersonId,FromDate,ToDate) VALUES (20, '2020-11-03','2021-06-30')
INSERT INTO #ExampelTable (PersonId,FromDate,ToDate) VALUES (30, '2000-11-03','2000-11-25')
INSERT INTO #ExampelTable (PersonId,FromDate,ToDate) VALUES (30, '2000-11-26','2000-11-30')


/*Creating CTE with FromDate in next row, together with that rows PersonId*/

;WITH NextDates AS
(
    SELECT  id
        ,   PersonId
        ,   FromDate
        ,   ToDate
        ,   LEAD(FromDate) OVER (PARTITION BY PersonId ORDER BY PersonId, FromDate) AS NextDate
        ,   LEAD(PersonId) OVER (PARTITION BY PersonId ORDER BY PersonId, FromDate) AS NextPersonId
    FROM #ExampelTable
),

/*Creating flags on the rows where one interval end */
RowNumbers AS
(
    SELECT  id
        ,   1 AS IntervalEnd
        ,   ROW_NUMBER() OVER ( PARTITION BY PersonId ORDER BY FromDate ) AS RowNr
    FROM    NextDates
    WHERE   PersonId = NextPersonId
        AND NextDate <> DATEADD(dd,1,ToDate)
        OR  NextDate IS NULL
)


SELECT  NextDates.Id
    ,   NextDates.PersonId
    ,   NextDates.FromDate
    ,   NextDates.ToDate
    ,   NextDates.NextDate
    ,   RowNumbers.IntervalEnd
    ,   RowNumbers.RowNr
    ,   NULL AS MinDate
    ,   NULL AS MaxDate
FROM    NextDates
    LEFT JOIN RowNumbers ON NextDates.id = RowNumbers.Id

This is how it looks with the extra columns I'm created. The red lines show the end of every interval. And the blue ones show which value I want to have in the "MinDate" and "MaxDate" columns. Row 1 is simple, it's 1 interval, end then MinDate = FromDate and MaxDate = ToDate.
Rows 2-5 I need FromDate from row 2 in every row in that interval (Row 2-5) in the MinDate column. And ToDate on row 5 in every MaxDate row in that column.

enter image description here

推荐答案

我不使用SQL Server,但在这种情况下,语法非常接近标准,并且此查询在SQL Server dbfiddle中工作:

with grps as (
  select id, personid, fromdate, todate, 
          sum(grp) over (partition by personid order by fromdate) grp
  from (
    select et.*, 
           case when lag(todate) over (partition by personid order by fromdate) 
                   = dateadd(dd, -1, fromdate) 
                then 0 else 1 end grp
    from #ExampelTable et) a )
select id, personid, fromdate, todate, 
       min(fromdate) over (partition by personid, grp) d1, 
       max(todate) over (partition by personid, grp) d2 
  from grps

Sql相关问答推荐

如何根据SQL中的列条件获取下一个时间戳?

解析键-值对,根据值 Select ,并使用SQL创建新列

Select 起始参数和截止参数之间的间隔,包括与期间重叠的参数

通过之前的连接-这是Oracle的错误吗?

在SQL查询中使用COALESS

按日期时间(不包括秒)连接表

带上最后日期(结果)

嵌套Json对象的SQL UPDATE WHERE

如何用HeidiSQL在Firebird中设置超时?

提取连续时间戳范围的SQL

存储过程太慢

SAS proc freq 或 proc sql 获取数据子集和整个数据的频率

复制行并根据 Oracle SQL 中其他表的值更改值

使用row_number() over partition by保留首次出现且值不为空的行的方法

为什么 get_json_object() 无法从存储在 Hive SQL 表中的 JSON 中提取值?

我需要遍历权重值表并确定每个权重是否有效

计算 PostgreSQL 中的平均会话长度

SQL - 使用子查询返回多行的 LIKE 命令

来自 SQL Server 的树层次 struct 图的 JSON

REGEXP 用于字符串格式化以对用空格分隔的字符和数字进行分组