如何在SQL Server中聚合“连续”记录?

时间:2018-07-25 10:00:48

标签: sql sql-server

我有一个这样的表:

name        date        record
A           20180725    1
A           20180725    2
B           20180721    5
B           20180721    7
B           20180721    8
B           20180721    9

,我希望汇总“连续”记录,预期结果如下:

name        date        r1    r2
A           20180725    1     2
B           20180721    5     5
B           20180721    7     9

其中r1r2是一组连续记录的开始和结束。

如何以良好的方式在sql server中实现此目标?

5 个答案:

答案 0 :(得分:2)

您可以使用lead()函数:

select name, min(record), max(record)
from ( select *, coalesce(lead(record) over (partition by date order by name) - record, 1) as grp
       from table
     ) t
group by name, grp;

答案 1 :(得分:2)

SELECT c1.name, 
        c1.[date],
        c1.record, 
        OA.record
                FROM contTable c1 

                    OUTER APPLY(SELECT TOP 1 co.name,co.date, co.record FROM contTable co WHERE co.record >= c1.record
                                        AND NOT EXISTS(SELECT 0 FROM conttable ce2 WHERE ce2.record = co.record + 1)
                                        ORDER BY co.record ASC) OA

                WHERE NOT EXISTS(SELECT 0 FROM contTable ce WHERE ce.record = c1.record - 1);

在代码,日期上输入破损

SELECT c1.name, 
        c1.[date],
        c1.record, 
        OA.record
                FROM contTable c1 

                    OUTER APPLY(SELECT TOP 1 co.name,co.date, co.record FROM contTable co WHERE 
                                co.record >= c1.record
                                        AND 
                                            (
                                                NOT EXISTS(SELECT 0 FROM conttable ce2 WHERE ce2.record = co.record + 1)
                                                OR EXISTS (SELECT 0 FROM contTable ce4 WHERE ce4.record = co.record +1 AND (ce4.date != co.date OR ce4.name != co.name) )
                                            )
                                        ORDER BY co.record ASC) OA

                WHERE NOT EXISTS(SELECT 0 FROM contTable ce WHERE ce.record = c1.record - 1) 
                    OR
                        EXISTS (SELECT 0 FROM contTable ce3 WHERE ce3.record = c1.record - 1 AND (ce3.date != c1.date OR ce3.name != c1.name) )

答案 2 :(得分:2)

@value

答案 3 :(得分:2)

这个问题是一个空白问题。对于您的情况,它有一个非常简单的解决方案。如果从record中减去序列,则当record的值是序列时,该值是恒定的。

所以:

select name, date, min(record), max(record)
from (select name, date, record,
             row_number() over (partition by name, date order by record) as seqnum
      from t
     ) t
group by name, date, (record - seqnum)

答案 4 :(得分:1)

select SS.name, SS.date, (
select TOP(1) record as [text()]
from t as FF
where FF.name = SS.name and FF.date = SS.date
order by name, date
FOR XML PATH('') ) as r1, 
(
select TOP(1) r2_xml.hour as [text()] 
from  t as TT
where TT.name = SS.name and TT.date = SS.date
order by name, date, record desc
FOR XML PATH('') ) as r2 
from  t as SS
group by SS.name, SS.date
order by 1