给出包含以下列的表:
数据:
1 | 2016-02-24
1 | 2016-02-23
1 | 2016-02-22
1 | 2016-02-20
2 | 2016-02-24
2 | 2016-02-14
3 | 2016-02-23
3 | 2016-02-22
3 | 2016-02-21
2 | 2016-01-30
2 | 2016-01-29
2 | 2016-01-28
2 | 2016-01-27
2 | 2016-01-26
2 | 2016-01-25
我想为每个用户返回最新的条目,并且从今天开始为特定用户返回。
案例1
userid = 1
返回值= 3 //用户错过第21天,所以连胜是22-24
案例2
userid = 2
返回值= 1 //即使用户有1/25 - 1/30的较长条纹,也不是他的最新连胜
案例3
userid = 3
返回值= 0 //今天用户错过了。因此,他今天没有连续几天计算
有关如何在T-SQL中完成此操作的任何想法?
更新1 :
根据响应,我修改了给出的示例查询,如下所示:然而,第二列中返回的值始终只有1或0,即使数据显示存在更多连续日期。
select
a.UserId,
sum(case when dayseq = '2016-02-01' then 1 else 0 end)
from
(select
t.*,
dateadd(day, 1 - row_number() over (partition by UserId order by DateCreated), DateCreated) as dayseq
from
fa.User_Journal t) a
where
DateCreated <= '2016-02-01'
group by
a.UserId;
更新2
以下查询进一步说明了该问题。下面提供的解决方案几乎解决了这个问题
在这个查询中,我说明了&#34;应该&#34;在@EndDate值下发生。通过取消对@EndDate的期望赋值的注释,您可以看到查询未根据提供的案例返回所需的结果。
非常感谢任何帮助。
DECLARE @Temp TABLE
(
UserId nvarchar(128),
DateCreated Date
)
INSERT INTO @TEMP (UserId, DateCreated) values ('uid123', '2016-01-19');
INSERT INTO @TEMP (UserId, DateCreated) values ('uid123', '2016-01-24');
INSERT INTO @TEMP (UserId, DateCreated) values ('uid123', '2016-01-28');
INSERT INTO @TEMP (UserId, DateCreated) values ('uid123', '2016-01-29');
INSERT INTO @TEMP (UserId, DateCreated) values ('uid123', '2016-02-01');
INSERT INTO @TEMP (UserId, DateCreated) values ('uid123', '2016-02-02');
INSERT INTO @TEMP (UserId, DateCreated) values ('uid123', '2016-02-03');
INSERT INTO @TEMP (UserId, DateCreated) values ('uid123', '2016-02-07');
INSERT INTO @TEMP (UserId, DateCreated) values ('uid123', '2016-01-19');
DECLARE @EndDate Date
SET @EndDate = '2016-02-03' -- Should return 5, as they are 5 consecutive days since @EndDate
--SET @EndDate = '2016-02-02' -- Should return 4, as they are 4 consecutive days since @EndDate
--SET @EndDate = '2016-02-19' -- Should return 1, as they are 4 consecutive days since @EndDate
--SET @EndDate = '2016-02-18' -- Should return 0, as they are 0 consecutive days since @EndDate
SELECT a.UserId,
SUM(CASE WHEN dayseq <= @EndDate then 1 else 0 end) -1 as FitStreak
from (select t.*,
dateadd(day,
1 - row_number() over (partition by UserId order by DateCreated),
DateCreated) as dayseq
from @Temp t
) a
where DateCreated <= @EndDate
group by a.UserId;
答案 0 :(得分:0)
我认为以下是您想要的:
"World"
这会从每个日期中减去一个序号,从0开始。然后将结果与“当前日期”进行比较 - 瞧,该值是初始序列的“当前日期”。
select t.UserId,
sum(case when dayseq = '2014-02-24' then 1 else 0 end)
from (select t.*,
dateadd(day,
row_number() over (partition by UserId order by DateEntered desc) - 1,
DateEntered) as dayseq
from t
) t
where DateEntered <= '2014-02-24'
group by t.UserId;
语句中的逻辑也可以在case
中。但是,结果将过滤掉没有日期的用户。
注意两个重要的假设:
这两个都可以轻松处理,但结果查询有点复杂。
编辑:
使用时间组件,截断值:
where
Here是一个说明固定代码的SQL小提琴。