ID Date flag_14 flag_21
1 1/1/2013 1 1
1 1/16/2013 1 0
1 1/19/2013 0 0
1 1/23/2013 0 1
1 1/26/2013 0 0
2 1/1/2013 1 1
2 1/18/2013 1 0
您好, 对不起,这可能是一个愚蠢的问题,但我真的可以使用一些帮助。 所以我想创建上面的输出。前两列是输入(id和日期)。逻辑是使用14天和21天作为截止值,通过比较当前记录和最后保留记录的日期来确定记录是否保持在相同的id内。始终保留每个id的第一条记录(flag为1表示“keep”,0表示不然)。
例如,对于id 1,如果截止值为21,则第二个记录的日期是2013年1月16日,也就是前一个记录的15天(这是第一个记录2013年1月1日),15< 15< ; 21因此第二条记录的标志为0.第三条记录相同,2013年1月19日和2013年1月1日相隔18天,18< 21 so flag = 0。但是对于第4条记录,2013年1月23日和2013年1月1日相隔22天,22> 21,所以保留此记录,flag = 1。然后将第5条记录与最后一条记录(现在是第4条记录)进行比较,2013年1月26日和2013年1月23日相隔3天,3< 21,所以flag = 0。
是否有一个简单的方法可以使用像partition by
?
谢谢!
答案 0 :(得分:1)
请尝试一下,按功能解决
with cte as
(
select o.*
from(
select yourid,yourdate,ROW_NUMBER () Over (partition by yourid order by (select(0)) ) as RN
from sedata
) as o
),
cte2 as
(
select r.*,
case when r.RN %2=0
then
(select DAY(r.YourDate) - DAY(r1.YourDate) where r.yourid = r1.yourid)
else
(select DAY( r.YourDate) - DAY(min(YourDate)) from sedata where r.yourid = r1.yourid )
end as Total
from cte r left join cte r1 ON r.RN-1 = r1.RN
)
select *
,case when Total is null then 1 when Total >14 and Total <21 then 1 else 0 end as flag_14 ,
case when Total is null then 1 when Total > 21 then 1 else 0 end as flag_21
from cte2 where Total is not null or RN=1
答案 1 :(得分:0)
如果我们正在讨论基于日期排序数据,例如在您的示例中,我们可以使用类似于以下代码的内容(注意,我只使用YourID和YourDate字段):
CREATE TABLE SeData(
YourID INT,
YourDate DATE
)
INSERT INTO SeData
VALUES (1,'2013-01-01')
, (1,'2013-01-16')
, (1,'2013-01-19')
, (1,'2013-01-23')
, (1,'2013-01-26')
;WITH Roll AS(
SELECT ROW_NUMBER() OVER (ORDER BY YourDate) ID
, YourID
, YourDate
FROM SeData
)
SELECT *
, (DAY(r1.YourDate) - DAY(r.YourDate)) AS NumberBetween -- just an example of comparing
FROM Roll r
INNER JOIN Roll r1 ON r.ID = (r1.ID - 1)
从那里,你可以比较从r到r1的日期,并更新/插入你需要的东西。
更新:我知道这适用于2012
(虽然它有LAG
和LEAD
),2008R2
并且不确定它是否会在2005年或以下。