2016-12-05 82 views
2

这是我的表中的记录删除记录在SQL Server中特定时间

field_date field_time field_id 
20161202 12:56:00 309073 
20161202 12:57:00 208901 
20161202 12:58:00 208901 
20161202 13:15:00 208901 

用相同的ID存在(208901)我想删除下面时间15分钟间隔的ID,例如在那里,这是结果我想

field_date field_time field_id 
20161202 12:56:00 309073 
20161202 12:57:00 208901 
20161202 13:15:00 208901 

与12时58分00秒的时间ID已被删除,因为它只有一个id第一记录1分钟间隔,但不13:15:00删除,因为时间间隔超过15从第一个记录开始分钟。

这里是我的代码,它仍然显示12:58:00记录,我想删除它,所以我将只显示间隔小于15分钟的记录,此代码只显示所有记录(不是我想要的重复记录),那里有什么问题?

SELECT * 
FROM tbl_name WHERE EXISTS (SELECT 1 FROM tbl_name t2 
     WHERE(t2.field_id = tbl_name.field_id AND 
     DATEDIFF(MINUTE, t2.field_time, tbl_name.field_time) <= 15) 
     ) 
     ORDER BY field_time 

回答

1

这个什么(对于SQL Server 2012+):

DECLARE @DataSource TABLE 
(
    [field_date] INT 
    ,[field_time] VARCHAR(8) 
    ,[field_id] INT 
); 

INSERT INTO @DataSource ([field_date], [field_time], [field_id]) 
VALUES (20161202, '12:56:00', 309073) 
     ,(20161202, '12:57:00', 208901) 
     ,(20161202, '12:58:00', 208901) 
     ,(20161202, '13:15:00', 208901); 

WITH DataSource ([field_date], [field_time], [field_id], [timeDiff]) AS 
(
    SELECT * 
     ,DATEDIFF(MINUTE, MIN([field_time]) OVER(PARTITION BY [field_date], [field_id] ORDER BY [field_time] ASC), [field_time]) 
    FROM @DataSource 
) 
SELECT * 
FROM DataSource 
WHERE [timeDiff] = 0 
    OR [timeDiff] > 15 
ORDER BY field_time; 

enter image description here

0
DECLARE @Data TABLE ([field_date] int, [field_time] varchar(8), [field_id] int); 

INSERT INTO @Data 
VALUES 
    (20161202, '12:56:00', 309073), 
    (20161202, '12:57:00', 208901), 
    (20161202, '12:58:00', 208901), 
    (20161202, '13:15:00', 208901) 
; 


;WITH data AS 
(
    SELECT 
     *, 
     -- A field easier to use for comparison, e.g. cross date 
     CONVERT(datetime, CAST(field_date AS char(8)), 112) + CONVERT(time, field_time) AS combined_time 
    FROM @Data 
) 
DELETE curr 
FROM 
    data curr 
    OUTER APPLY 
    (
     SELECT TOP 1 * 
     FROM data prev 
     WHERE 
      prev.field_id = curr.field_id 
      -- assume the record does not contain duplicate record of field_time 
      AND prev.combined_time < curr.combined_time 
     ORDER BY combined_time DESC 
    ) AS prev 
WHERE DATEDIFF(MINUTE, prev.combined_time, curr.combined_time) <= 15 

-- Result 
SELECT * FROM @Data 
0

尝试如下:

DECLARE @DATEDIFF TABLE (ID INT IDENTITY(1,1),FIELD_DATE DATE,FIELD_TIME TIME,FIELD_ID INT) 
INSERT INTO @DATEDIFF SELECT * FROM TABLE1 
DECLARE @FIELD_ID INT,@FIELD_DATE DATE,@FIELD_TIME TIME,@ID INT,@NEXT_TIME TIME,@NEXT_DATE DATE 

DECLARE C CURSOR FOR 
SELECT DISTINCT FIELD_ID FROM @DATEDIFF 
OPEN C 
FETCH NEXT FROM C INTO @FIELD_ID 
WHILE @@FETCH_STATUS=0 
BEGIN 

    DECLARE D CURSOR FOR 
    SELECT ID,FIELD_DATE ,FIELD_TIME FROM @DATEDIFF WHERE FIELD_ID = @FIELD_ID 
    OPEN D 
    FETCH NEXT FROM D INTO @ID,@FIELD_DATE,@FIELD_TIME 
    WHILE @@FETCH_STATUS=0 
    BEGIN 
    SET @NEXT_TIME=(SELECT FIELD_TIME FROM @DATEDIFF WHERE [email protected]+1 AND FIELD_ID = @FIELD_ID) 
    SET @NEXT_DATE=(SELECT FIELD_DATE FROM @DATEDIFF WHERE [email protected]+1 AND FIELD_ID = @FIELD_ID) 

    IF EXISTS(SELECT FIELD_TIME FROM @DATEDIFF WHERE [email protected]+1 AND FIELD_ID = @FIELD_ID) 
    BEGIN 
    IF (DATEDIFF (MI,CAST(@FIELD_DATE AS VARCHAR(100))+' '+CAST(@FIELD_TIME AS VARCHAR(100)),CAST(@NEXT_DATE AS VARCHAR(100))+' '+CAST(@NEXT_TIME AS VARCHAR(100))))<15 
    DELETE FROM @DATEDIFF WHERE [email protected]+1 AND FIELD_ID = @FIELD_ID 
    END 
    FETCH NEXT FROM D INTO @ID,@FIELD_DATE,@FIELD_TIME 
    END 
    CLOSE D 
    DEALLOCATE D 

FETCH NEXT FROM C INTO @FIELD_ID 
END 
CLOSE C 
DEALLOCATE C 

SELECT * FROM @DATEDIFF 
0

试试这个,

DECLARE @DataSource TABLE 
(
    [field_date] INT 
    ,[field_time] VARCHAR(8) 
    ,[field_id] INT 
); 

INSERT INTO @DataSource ([field_date], [field_time], [field_id]) 
VALUES (20161202, '12:56:00', 309073) 
     ,(20161202, '12:57:00', 208901) 
     ,(20161202, '12:58:00', 208901) 
     ,(20161202, '13:15:00', 208901); 
;with CTE as 
(
select *,ROW_NUMBER()over(PARTITION by [field_date], [field_id] ORDER BY [field_time] ASC)rn from @DataSource A 
) 

, CTE1 as 
(
select *,1 flg from cte where rn=1 
UNION ALL 
select c.*,case when (DATEDIFF(MINUTE, c1.field_time,c.field_time) <= 15) then 0 else 1 end from cte c 
inner join cte1 c1 on c1.[field_id]=c.[field_id] 
where c.rn=c1.rn+1 
) 
select * from cte1 
where flg=1 
order by [field_id],field_time