SQL Select: how to return count of consecutive values from an ordered data set

The following is a subset of a table I have in a SQL Server 2008 database.

I am trying to output the Serial Number , the LID with the greatest count of consecutive LID values, and the actual count. Important to note that the table is ordered by the Last Updated Date value descending (this condition is critical). It can be grouped by Serial Number or ordered by Serial Number ascending or descending... whatever is more efficient and makes sense.

Here's what the data looks like:

[Serial Number]  [LID]   [Last Updated Date]
--------------------------------------    
123456            AAA     2012-09-24
123456            AAA     2012-09-23
123456            AAA     2012-09-22
123456            AAA     2012-09-21
123456            BBB     2012-09-20
123456            BBB     2012-09-19
123456            AAA     2012-09-18
123456            AAA     2012-09-17
123456            AAA     2012-09-16
234567            BBB     2012-09-24
234567            BBB     2012-09-23
234567            AAA     2012-09-22

The desired output to the table is:

[Serial Number]     [LID]     [LID Count]
-------------------------------------------    
123456            AAA     4
234567            BBB     2

I am at a loss. I've tried using

ROW_NUMBER() OVER(PARTITION BY [Service Tag], [LID]
                  ORDER BY [Last Updated Date] DESC) 

but all that does is break up my descending date order and I end up with the count and the LID that occurs the most during the range of dates.

Thanks in advance for any assistance you can provide!

Best Regards,

VP


Have a look at the example below

SQL Fiddle Demo

DECLARE @Table TABLE(
        [Serial Number] INT,
        [LID] VARCHAR(50),
        [Last Updated Date] DATETIME
)

INSERT INTO @Table SELECT 123456,'AAA','2012-09-24'
INSERT INTO @Table SELECT 123456,'AAA','2012-09-23'
INSERT INTO @Table SELECT 123456,'AAA','2012-09-22'
INSERT INTO @Table SELECT 123456,'AAA','2012-09-21'
INSERT INTO @Table SELECT 123456,'BBB','2012-09-20'
INSERT INTO @Table SELECT 123456,'BBB','2012-09-19'
INSERT INTO @Table SELECT 123456,'AAA','2012-09-18'
INSERT INTO @Table SELECT 123456,'AAA','2012-09-17'
INSERT INTO @Table SELECT 123456,'AAA','2012-09-16'
INSERT INTO @Table SELECT 234567,'BBB','2012-09-24'
INSERT INTO @Table SELECT 234567,'BBB','2012-09-23'
INSERT INTO @Table SELECT 234567,'AAA','2012-09-22'

;WITH Vals AS (
        SELECT  *,
                ROW_NUMBER() OVER(ORDER BY [Serial Number],[Last Updated Date] DESC) ROWID
        FROM    @Table
)
, ValsNext AS (
        SELECT  v.[Serial Number],
                v.LID,
                v.[Last Updated Date],
                v.ROWID,
                MIN(vn.ROWID) NextRowID
        FROM    Vals v LEFT JOIN
                Vals vN ON  v.[Serial Number] = vn.[Serial Number]
                        AND v.LID != vn.LID
                        AND v.ROWID < vn.ROWID
        GROUP BY    v.[Serial Number],
                    v.LID,
                    v.[Last Updated Date],
                    v.ROWID
)
, ValDiffs AS (
        SELECT  vn.[Serial Number],
                vn.LID,
                vn. NextRowID - vn.ROWID Consecutive
        FROM    ValsNext vn
)
, Serials AS (
        SELECT  [Serial Number],
                MAX(Consecutive) MaxConsecutive
        FROM    ValDiffs
        GROUP BY    [Serial Number]
)
SELECT  vd.*
FROM    Serials s INNER JOIN
        ValDiffs vd ON  s.[Serial Number] = vd.[Serial Number]
                    AND s.MaxConsecutive = vd.Consecutive

Here's a solution

;with cte as (
  select sn, lid, ludate,
    datediff(d,row_number() over (
    partition by sn,lid
    order by ludate),ludate) dd
  from xtable
), cte2 as (
  select sn,lid,dd,count(*)c,
      rn=row_number() over (partition by lid
                            order by count(*) desc)
  from cte
  group by sn,lid,dd
)
select sn [Serial Number], lid, c [Count]
from cte2
where rn=1

The first CTE uses a complex DATEADD expression to group together consecutive days, tagged using the column dd .
The second CTE is a regular row numbering of the counts.

链接地址: http://www.djcxy.com/p/64242.html

上一篇: 如何将Linux中安装的Qt从一个版本升级到更高版本

下一篇: SQL选择:如何从有序数据集中返回连续值的计数