Microsoft T-SQL计数连续记录

时间:2010-05-07 18:35:23

标签: sql-server tsql 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 ------------------------------------------ ---------------------------------
乔尔,非常感谢你在下面的回复!我需要它来运行大约60分钟的关键生产工作 现在工作在2分钟内完成!!

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

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

1 个答案:

答案 0 :(得分: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