Sql server 将表格问题分组
我的表有四个字段:ID、DateBeg、DateEnd和RankID。RankID值是ID字段在DateBeg asc上的排名。以下是示例数据:Sql server 将表格问题分组,sql-server,sql-server-2012,group-by,Sql Server,Sql Server 2012,Group By,我的表有四个字段:ID、DateBeg、DateEnd和RankID。RankID值是ID字段在DateBeg asc上的排名。以下是示例数据: ID |RankID | DateBeg | DateEnd | ---|-------|-------------------------- 1 | 1 |01-01-2016 |04-01-2016 | 1 | 2 |05-01-2016 |11-02-2016 | 1 | 3 |12-02-201
ID |RankID | DateBeg | DateEnd |
---|-------|--------------------------
1 | 1 |01-01-2016 |04-01-2016 |
1 | 2 |05-01-2016 |11-02-2016 |
1 | 3 |12-02-2016 |15-02-2016 |
1 | 4 |16-02-2016 |19-02-2016 |
1 | 5 |23-02-2016 |25-02-2016 |
4 | 2 |05-01-2016 |07-01-2016 |
4 | 3 |08-01-2016 |12-01-2016 |
5 | 1 |04-01-2016 |06-01-2016 |
现在,我想对ID记录进行分组,这些记录的DateBeg值比前一个rank记录的DateEnd值晚1天。如果它为null,则也必须包含它。
此示例表的预期结果为:
ID | Min(DateBeg)|Max(DateEnd)|
---|-------------|----------------
1 |01-01-2016 |19-02-2016 |
1 |23-02-2016 |25-02-2016 |
4 |05-01-2016 |12-01-2016 |
5 |04-01-2016 |06-01-2016 |
希望您能帮助我,提前谢谢。试试下面的方法。我假设您的datebeg和Dateend是uin日期数据类型格式。否则,您需要转换为日期数据类型进行比较
SELECT ID,MIN(DATEBEG),MAX(DateEnd) FROM
(
SELECT ID,(DATEBEG),ROW_NUMBER()OVER(PARTITION BY ID ORDER BY ID) RNO,
(DateEND),CASE WHEN DATEBEG=LAG( DATEADD(DAY,1,[DateEnd]))
OVER(PARTITION BY ID ORDER BY ID)THEN 1 END NO
FROM #TABLE1
)A
GROUP BY ID,ISNULL(NO,RNO)
ORDER BY ID
更新:-
试试下面。如果您的数据集中有唯一的ud和rank id组合,则它将适用于所有场景,否则使用row_编号并生成唯一编号
SELECT ID,MIN(DATEBEG),MAX(DATEEND) FROM
(
SELECT ID,
RANKID,
datebeg,
DateEnd,
CASE
WHEN Dateadd(DAY, -1, datebeg) = Lag( DateEnd) OVER(PARTITION BY ID ORDER BY ID)
OR Dateadd(DAY, 1, dateEND) = LEAD( DateBeg) OVER(PARTITION BY ID ORDER BY ID)
THEN 1
ELSE 0
END NO
FROM #Table1
)A
GROUP BY ID,CASE WHEN NO=0 AND ID<>RANKID THEN RANKID ELSE NO END
ORDER BY ID
以下是算法:
检测间隙。立即为每个不符合先前记录的记录留出间隙1。因此,开始新组的每条记录都会标记为1。
建立一个总的差距数字。因此,一个组的所有记录都得到相同的编号。
按找到的组分组,并显示每个组的最小开始日期和最大结束日期。
SQL Server查询:
select id, min(datebeg), max(dateend)
from
(
select
id,
datebeg,
dateend,
sum(gap) over (partition by id order by datebeg) as grp
from
(
select
id,
datebeg,
dateend,
case when datebeg <>
dateadd(day, 1, lag(dateend) over (partition by id order by datebeg))
then 1 else 0 end as gap
from mytable
) with_gap_flags
) with_group_numbers
group by id, grp
order by id, grp;
SQL fiddle:您使用的SQL server 2012是哪个版本的?RankID的用途是什么?这看起来是多余的,因为顺序与日期相同。还是RankID有另一个特殊的含义?如果没有,我会将其从表中删除。这不正确。请看这里:@ThorstenKettner,你说得对,在我们得到间隙后,这个查询将返回错误的结果。@TedoG。即使上面的答案也给出了错误的结果。我很快就要更新我的帖子了。@Buddi,当上面的查询为假时,我没有发现任何情况,你能举个例子吗?@TedoG。无法回忆起那种情况。当我测试上述解决方案时,它失败了。我不确定这是什么情况。我正在接受这个答案,因为这是一个非常完整的答案。