2016-12-05 88 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