确定最长的"条纹"在SQL Server中?

时间:2016-04-10 00:55:28

标签: sql-server sql-server-2008

我看了一些其他的" Streak"问题,但没有什么与我的情况完全相同,因为他们的情况包括连续的ID。

我有下面显示的数据,我正在尝试确定最长的"天"每个用户都拥有"是"没有收到" No"的熟练程度。这些日子不一定是连续的。每一天实际上都是一项工作" Shift"所以我希望能够说'#34;用户X有8个班次而没有' No'。&# 34;为每个用户。

ProficiencyUser ProficiencyDateAdded       ProficiencyMet
JDOE            2016-04-09 19:35:51.590    Yes
RTHOMPSON       2016-04-09 19:16:42.237    Yes
MMOUSE          2016-04-09 18:59:03.263    Yes
MMOUSE          2016-04-09 18:54:33.210    Yes
MMOUSE          2016-04-09 18:26:55.750    No
MMOUSE          2016-04-06 18:54:33.210    Yes
MMOUSE          2016-03-26 13:54:33.210    Yes
MMOUSE          2016-04-09 18:54:33.210    Yes

我使用的是SQL Server 2008 R2。

2 个答案:

答案 0 :(得分:1)

此查询返回每个用户的最长条纹:

;WITH
TestUser AS -- Convert 'Yes'/'No' to int
(
SELECT
    t.[ProficiencyUser]
    ,t.[ProficiencyDateAdded]
    ,ProficiencyMet = CASE WHEN t.[ProficiencyMet] = 'Yes' THEN 1 ELSE 0 END
FROM [Test] t
)
,ByDates AS -- Get Result per Day per User
(
SELECT
    u.[ProficiencyUser]
    ,ProficiencyDate = CAST(u.[ProficiencyDateAdded] AS date)
    ,ProficiencyMet = CASE WHEN COUNT(u.[ProficiencyMet]) = SUM(CAST(u.[ProficiencyMet] as int)) THEN 1 ELSE 0 END
FROM [TestUser] u
GROUP BY [u].[ProficiencyUser], CAST(u.[ProficiencyDateAdded] AS date)
)
,UserDayRank AS -- rank user days
(
SELECT
    Id = RANK() OVER(PARTITION BY [ProficiencyUser] ORDER BY [ProficiencyDate])
    ,[ProficiencyUser]
    ,[ProficiencyDate]
    ,[ProficiencyMet]
FROM [ByDates]
)
,UserSeq AS -- filter user days, and get islands and gaps per user
(
SELECT
    [Id]
    ,[ProficiencyUser]
FROM [UserDayRank]
WHERE [ProficiencyMet] = 1
)
,Islands AS -- number each user's island
(
SELECT
    Id
    ,GroupId = Id - ROW_NUMBER() OVER(PARTITION BY [ProficiencyUser] ORDER BY [Id])
    ,[ProficiencyUser]
FROM [UserSeq]
)
,IslandLen AS -- get length of user's islands
(
SELECT
    L = COUNT([GroupId])
    ,[ProficiencyUser]
FROM [Islands]
GROUP BY [ProficiencyUser], [GroupId]
)
-- finally get the longest user's island for each user
SELECT [ProficiencyUser], L = MAX(L) FROM [IslandLen]
GROUP BY [ProficiencyUser]
ORDER BY MAX(L) DESC, [ProficiencyUser]

答案 1 :(得分:0)

在修改后的要求(见评论)中,我出现的是从今天的日期到每个用户的最后一个“否”条目的“连胜”(连续天数):

SELECT l.*, DATEDIFF(DAY, l.ProficiencyDateAdded, GETDATE()) AS 'DaysAgo'
FROM
(SELECT ProficiencyUser, MAX(ProficiencyDateAdded) AS 'ProficiencyDateAdded'
FROM   ProficiencyTable
WHERE ProficiencyMet LIKE 'No'
GROUP BY ProficiencyUser) l
ORDER BY DaysAgo DESC