Microsoft T-SQL计数连续记录

Jef*_*ffW 4 t-sql sql-server count

问题: 从每个人的最近一天开始计算每个人因为好的而获得0分的连续天数.

要使用的示例数据:

Date       Name Points
2010-05-07 Jane 0  
2010-05-06 Jane 1  
2010-05-07 John 0  
2010-05-06 John 0  
2010-05-05 John 0  
2010-05-04 John 0  
2010-05-03 John 1  
2010-05-02 John 1  
2010-05-01 John 0

预期答案:

Jane在5月7日表现糟糕,但前一天表现不错.所以Jane最近才连续第一天不好.约翰在5/7,5/6,5/5和5/4再次表现糟糕.5/3他表现不错.约翰连续四天都很糟糕.

用于创建样本数据的代码:

IF OBJECT_ID('tempdb..#z') IS NOT NULL BEGIN DROP TABLE #z END
select getdate() as Date,'John' as Name,0 as Points into #z 
insert into #z values(getdate()-1,'John',0)
insert into #z values(getdate()-2,'John',0)
insert into #z values(getdate()-3,'John',0)
insert into #z values(getdate()-4,'John',1)
insert into #z values(getdate(),'Jane',0)
insert into #z values(getdate()-1,'Jane',1)
select * from #z order by name,date desc

首先,我很抱歉这个系统很新,并且无法弄清楚如何正常工作界面和发布.

2010-05-13 --------------------------------------------- ------------------------------
Joel,非常感谢您在下面的回复!我需要它来运行大约60分钟的关键生产工作.
现在工作在2分钟内运行!!

是的,在我的案例中有一个条件我需要解决.我的来源总是只记录最近那些不好的人,这对我来说不是问题.然而,我确实需要处理它们永远不会好的记录,并使用左连接来添加回记录并给它们一个日期,以便计数适用于所有人.

再次感谢你的帮助.我更多地了解了基于SET的逻辑以及如何处理它,这对我的生产工作来说是一个巨大的好处.

Joe*_*orn 8

这里的基本解决方案是首先构建一个集合,其中包含每个人的姓名以及该人员良好的最后一天的值.然后将此集合加入原始表格并按名称分组,以查找每个人的最后一个好日子的天数.您可以在CTE,视图或不相关的派生表(子查询)中构建集 - 任何这些都可以工作.我的示例使用CTE.

请注意,虽然概念是合理的,但这个具体示例可能无法准确返回您想要的内容.这里你的实际需求取决于那些一直没有好过的人和最近没有坏过的人想要发生什么(也就是说,你可能需要一个左连接来向昨天表现良好的用户展示).但这应该让你开始:

WITH LastGoodDays AS
(
  SELECT MAX([date]) as [date], name
  FROM [table]
  WHERE Points > 0
  GROUP BY name
)
SELECT t.name, count(*) As ConsecutiveBadDays
FROM [table] t
INNER JOIN LastGoodDays lgd ON lgd.name = t.name AND t.[date] > lgd.[date]
group by t.name
Run Code Online (Sandbox Code Playgroud)