2016-04-13 39 views
1

Yinelenen kayıt arasındaki tarih farkı 96 saatten fazla veya 4 gün varsa yinelenen kayıt ve dönüş kaydını yoksayan yinelenen kayıt almak zorundayım ilk giriş veya en eski tarih. Böyle My masa görünüm:tarih farkı eşit veya 4 gün veya 96 saatten fazla olduğunda yinelenen satırların nasıl döndürüleceği

ID   SDATE 
----------- ----------------------- 
1   2016-04-13 14:54:18.983 
1   2016-04-08 12:55:47.907 
2   2016-04-13 14:54:18.983 
3   2016-04-13 14:54:18.983 
4   2016-04-13 14:54:18.983 
5   2016-04-13 14:54:18.983 
5   2016-04-11 12:55:47.907 
6   2016-04-13 14:54:18.983 
6   2016-04-13 14:54:18.983 

Beklenen sonuç:

ID   SDATE 
----------- ----------------------- 
1   2016-04-13 14:54:18.983 
1   2016-04-08 12:55:47.907 
2   2016-04-13 14:54:18.983 
3   2016-04-13 14:54:18.983 
4   2016-04-13 14:54:18.983  
5   2016-04-11 12:55:47.907 
6   2016-04-13 14:54:18.983 

i sorguyu aşağıdaki çalıştı ama çalışmıyor.

WITH tt AS (
SELECT 1 as ID, GETDATE() as SDATE 
UNION ALL 
SELECT 1 as ID, '2016-04-09 12:55:47.907' as SDATE 
UNION ALL 
SELECT 2 as ID, GETDATE() as SDATE 
UNION ALL 
SELECT 3 as ID, GETDATE() as SDATE 
UNION ALL 
SELECT 4 as ID, GETDATE() as SDATE 
UNION ALL 
SELECT 5 as ID, GETDATE() as SDATE 
UNION ALL 
SELECT 5 as ID, '2016-04-11 12:55:47.907' as SDATE 
UNION ALL 
SELECT 6 as ID, GETDATE() as SDATE 
UNION ALL 
SELECT 6 as ID, GETDATE() as SDATE 
) 
SELECT MIN(SDATE) as SDATE, ID FROM tt as tbl 
GROUP BY ID, DATEADD(HH, DATEDIFF(HH,0,SDATE) + 96,0) 
+1

ne olur gereken biri 'id' üç kayıt aşağıdaki varsa değiştirebilir sütunları görmezden? '{'2016-04-01 06: 00: 00.000', '2016-04-03 18: 00: 00.000', '2016-04-06 06: 00: 00.000'}'? Her kayıt 4 günden daha kısadır, ancak ilk ve son kayıt 5 gün arayla ayrılır. – MatBailie

+0

3 yinelenen kimlik, ilk tarih - '1/4/2016', ikinci tarih -' 3/4/2016' ve üçüncü tarih '6/4/2016' varsa, tanımınıza göre ikinci bir yinelenen olur birinci ve üçüncü, ikinci bir kopyasıdır. Hangisi silinmeli? – sagi

+2

@MatBailie Hah, aynı soru, aynı tarihler. – sagi

cevap

1

Aşağıdaki sorgu beklenen sonucu verir, satır içi yorum ekledi:

-- Simply grouping each ID and get unique row with minimum date 
SELECT MIN(SDATE) [SDate], ID 
FROM tt 
GROUP BY ID 

UNION 

-- Get the row with each ID's difference is more than 96 hours 
SELECT D.MaxDate [SDate], D.ID 
FROM (
    SELECT MIN(SDATE) [MinDate], MAX(SDATE) [MaxDate], ID 
    FROM tt 
    GROUP BY ID 
) D 
WHERE DATEDIFF(HH, D.MinDate, D.MaxDate) >= 96 
+0

İkna olmadım. 1, 4, 7, 10, 13'nci tarihleri ​​varsa. Bu cevap, son üç sonuçta her birinin sadece 3 günlük bir boşluğa sahip olmasına rağmen "1, 7, 10, 13" i döndürecektir. Bu yanlış bir şey değil, sadece OP'nin böyle bir durumun gerekliliklerinden çok uzak olduğunu söylemek mümkün değil. – MatBailie

0

sorgusu altında deneyin, ben iyi çalışıyor test ettik. içinde

Eğer nokta (HH veya GÜN)

-- drop table #temptbl

WITH tt AS (
SELECT 1 as ID, GETDATE() as SDATE 
UNION ALL 
SELECT 1 as ID, '2016-04-09 12:55:47.907' as SDATE 
UNION ALL 
SELECT 2 as ID, GETDATE() as SDATE 
UNION ALL 
SELECT 3 as ID, GETDATE() as SDATE 
UNION ALL 
SELECT 4 as ID, GETDATE() as SDATE 
UNION ALL 
SELECT 5 as ID, GETDATE() as SDATE 
UNION ALL 
SELECT 5 as ID, '2016-04-11 12:55:47.907' as SDATE 
UNION ALL 
SELECT 6 as ID, GETDATE() as SDATE 
UNION ALL 
SELECT 6 as ID, GETDATE() as SDATE 
) 
SELECT Id,SDATE,case when DATEDIFF(HH,SDATE,GETDATE()) >94 THEN 0 else 1 end AS ignore, 
    ROW_NUMBER() OVER (PARTITION BY tt.ID ORDER BY tt.SDATE desc) as Rowid 
INTO #temptbl 
FROM tt 
SELECT Id, sdate from #temptbl 
WHERE (#temptbl.ignore = 0) or (#temptbl.Rowid = 1) 

0
declare @table table 
(
ID int,   SDATE datetime) 
insert into @table 
(
ID  ,SDATE) 
values 
(1,'2016-04-13 14:54:18'), 
(1,'2016-04-08 12:55:47'), 
(2,'2016-04-13 14:54:18'), 
(3,'2016-04-13 14:54:18'), 
(4,'2016-04-13 14:54:18'), 
(5,'2016-04-13 14:54:18'), 
(5,'2016-04-11 12:55:47'), 
(6,'2016-04-13 14:54:18'), 
(6,'2016-04-13 14:54:18') 


;with cte as 
(
select id,min(sdate) mindate,max(sdate) maxdate, datediff(dd,min(sdate),max(sdate)) daysdiff,count(*) as Dups 
from @table 
group by id 
) 
select cte.id, t.sdate 
from cte 
join @table t on t.id = cte.id 
where cte.dups > 1 and cte.daysdiff > 4 
union all 
select cte.id, 
     mindate 
from cte 
where (cte.dups > 1 and cte.daysdiff <= 4) or 
     cte.dups = 1