需要清理日志(SQL必须删除除第一天之外的所有条目)

时间:2014-09-26 11:09:09

标签: sql sql-server

我通过监听他们何时发言,在不同的研讨会上记录发言人。表格定义如下。

但在过去的几个月里,数据库的规模不断扩大,我并不需要每5分钟登录一次。实际上,只要每天为他们出现的每个房间记录一次扬声器就足够了。所以我想删除所有其他房间。在下面的示例中,Scott有两个发言会话。一个在416房间从1:33开始,另一个从417房间的5:00开始,所以我只需要那两个条目。斯科特的其余部分可以删除。 Matt的演讲会从1:42开始,我想保留第一个条目并删除其他3个。

基本上我想要保留的是为每个speakerNo,RoomName,SpeakerName选择不同的日期。如何创建SQL以删除其余的SQL?首先我需要能够选择它,但我不知道我对SQL是一个新手。

ID  Time            SpeakerNo   RoomName    SpeakerName
409 2014-06-11 01:33    7646        416     Scott Olsen
410 2014-06-11 01:38    7646        416     Scott Olsen
410 2014-06-11 01:43    7646        416     Scott Olsen
410 2014-06-11 01:48    7646        416     Scott Olsen
411 2014-06-11 01:42    5140        210     Matt Jonson
411 2014-06-11 01:47    5140        210     Matt Jonson
411 2014-06-11 01:52    5140        210     Matt Jonson
411 2014-06-11 01:47    5140        210     Matt Jonson
412 2014-06-11 05:00    7646        417     Scott Olsen

CREATE TABLE [OnlineSpeakers]
(
   [ID] INT NOT NULL IDENTITY (1,1),
   [Time] DATETIME NOT NULL,
   [SpeakerNo] INT NOT NULL,
   [RoomName] NVARCHAR(100),
   [SpeakerName] NVARCHAR(100)
);

ALTER TABLE [OnlineSpeakers] ADD CONSTRAINT [PK_OnlineSpeakers] PRIMARY KEY ([ID]);

CREATE UNIQUE INDEX [UQ__OnlineSpeakers__000000000000000E] ON [OnlineSpeakers] ([ID] ASC);

2 个答案:

答案 0 :(得分:2)

我喜欢将CTE和窗口函数用于此目的:

with todelete  as(
      select os.*, row_number() over (partition by cast(time as date), speakerno, roomname
                                      order by time) as seqnum
      from onlinespeakers
     )
delete from todelete
    where seqnum > 1;

并非所有数据库都支持这些构造。但是你的语法似乎是SQL Server。

答案 1 :(得分:1)

以下查询将为您提供实际需要的结果:

SELECT SpeakerNo, RoomName , TO_CHAR(Time , 'DD-MM-YYYY') SPEAK_DATE  ,
MIN(TIME) SPEAK_START_DATE_TIME
FROM OnlineSpeakers
GROUP BY SpeakerNo, RoomName,TO_CHAR(Time , 'DD-MM-YYYY') ;

对于删除,你可以尝试类似的东西,

DELETE FROM OnlineSpeakers A LEFT JOIN
(
    SELECT SpeakerNo, RoomName , TO_CHAR(Time , 'DD-MM-YYYY') SPEAK_DATE  , 
    MIN(TIME) SPEAK_START_DATE_TIME
    FROM OnlineSpeakers
    GROUP BY SpeakerNo, RoomName,TO_CHAR(Time , 'DD-MM-YYYY')
) AS B
ON A.SPEAKERNO = B.SPEAKERNO AND A.ROOMNAME = B.ROOMNAME 
AND A.TIME = B.SPEAK_START_DATE_TIME;