2016-06-23 86 views
2

我有如下表:删除从表中共享相同ID的所有行

Name  | ID | date | 
Login | 1 | somedate | 
Command | 1 | somedate | 
Command | 1 | somedate | 
Login | 2 | somedate | 
Command | 1 | somedate | 
Command | 2 | somedate | 
Logout | 1 | somedate | 
Command | 2 | somedate | 

我想从一个登录名和共享相同ID的注销之间的表都删除,但保留一切那里。 somedate字段是日期时间。表中可能会有更多登录/注销,并且会有登录没有相应的注销。我想让它保持在那里,因为注销最终会出现。

我正在考虑使用游标。哪一个对性能来说最好呢?决赛桌可能有几百万行。

中删除该表应该是这样的后:

Name | ID | 
Login | 2 | 
Command | 2 | 
Command | 2 | 

编辑:登录和注销,包括登录/注销行之间删除所有内容。

+0

与chris更新一样,尝试获取所有具有“注销”条目的ID。做一个直接删除。 – an33sh

+0

您的结果令我困惑,您是否想要完全删除ID 1,因为它既有登录又有注销外观? –

+0

@RichBenner是的,包括登录和注销。 – MisterM

回答

2

假设每个注销有删除一切相应的登录,你可以试试这个:

DELETE 
FROM yourTable 
WHERE ID IN 
(
    SELECT ID 
    FROM yourTable 
    WHERE Name LIKE 'Logout' 
) 

其结果将是:

Name | ID | 
Login | 2 | 
Command | 2 | 
Command | 2 | 

如果你想与 “登录” 和 “注销” 行过,你可以这样做:

DELETE 
FROM yourTable 
WHERE ID IN 
(
    SELECT ID 
    FROM yourTable 
    WHERE Name LIKE 'Logout' 
) 
AND Name NOT LIKE 'Login' 
AND Name NOT LIKE 'Logout' 

你会得到这样的结果:

Name | ID | 
Login | 1 | 
Login | 2 | 
Command | 2 | 
Logout | 1 | 
Command | 2 | 
+0

在这个例子中,ID似乎不是主键,所以这将删除所有记录,包括登录和注销,我不认为这是OP要求的内容 – Milney

+2

@Milney看看他的预期结果。他也想删除登录和注销。 –

+0

它完美的作品。 Upvoted它。 – MisterM

1

我想了解我的第一篇文章你的问题,编辑更正:

delete from yourTable 
where id in (select yt.Id from yourtable yt 
     inner join yourtable yt2 on yt2.Id = yt.Id and yt2.Name like 'Logout' 
     where yt.Name like 'Login') 

以上应该从你的表,其中登录有相应的注销

+0

我想他只是没有很好地解释他自己。 – sagi

+0

重读并更正了答案 – Chris

+0

在这个例子中,ID似乎不是主键,所以这将删除所有记录,包括登录和注销,我不认为这是OP向我要求的 – Milney

1
select distinct(id) into @id from your_table where Name = 'Logout'; -- will give you all user id that need to delete 
delete from your_table where id in (@id); 
+0

在这个例子中,ID似乎不是主键,所以这将删除所有记录,包括登录和注销,我不认为这是OP要求的 – Milney

+0

感谢您指出。 OP提到了Login和Logout之间的所有内容,但是在预期结果OP中不想获得两个条目。 认为他需要编辑帖子:) – an33sh

2

有是一些不明确的情况(如果有没有匹配登录的命令会发生什么?如果登录与登出同一天,我们假设登出后登录?等等),但这应该给你一个出发点;

它删除它们登录或注销记录的所有记录,其中记录有较早登录,以及相同ID的注销记录;

WITH TestData AS (
    SELECT 'Login' as Name, 1 AS ID, cast('01/01/2000' as date) as Date 
    UNION ALL 
    SELECT 'Command' as Name, 1 AS ID, cast('02/01/2000' as date) as Date 
    UNION ALL 
    SELECT 'Command' as Name, 1 AS ID, cast('03/01/2000' as date) as Date 
    UNION ALL 
    SELECT 'Logout' as Name, 1 AS ID, cast('04/01/2000' as date) as Date 
    UNION ALL 
    SELECT 'Command' as Name, 1 AS ID, cast('05/01/2000' as date) as Date 
    UNION ALL 
    SELECT 'Command' as Name, 2 AS ID, cast('01/01/2000' as date) as Date 
) 
DELETE FROM TestData td1 
-- Delete any records which are not login or logout 
WHERE Name <> 'Login' AND Name <> 'Logout' 
-- Where there is an earlier Login 
AND EXISTS (SELECT 1 from TestData td2 where td2.Name = 'Login' AND td1.Id = td2.Id AND td2.Date <= td1.Date) 
-- and a later logout 
AND EXISTS (SELECT 1 from TestData td3 where td3.Name = 'Logout' AND td1.Id = td3.Id AND td3.Date >= td1.Date) 
2

让我们来做一些测试数据;

IF OBJECT_ID('tempdb..#TestData') IS NOT NULL DROP TABLE #TestData 
GO 
CREATE TABLE #TestData (Name varchar(7), ID int, Date datetime) 
INSERT INTO #TestData (Name, ID, Date) 
VALUES 
('Login',1,'2016-06-23 12:00:00') 
,('Command',1,'2016-06-23 12:05:00') 
,('Command',1,'2016-06-23 12:10:00') 
,('Login',2,'2016-06-23 12:15:00') 
,('Command',1,'2016-06-23 12:20:00') 
,('Command',2,'2016-06-23 12:25:00') 
,('Logout',1,'2016-06-23 12:30:00') 
,('Command',2,'2016-06-23 12:35:00') 

我会使用这样的查询。已连接的查询将返回登录和注销日期时间之间的特定ID的所有行。它不会删除ID 2的任何内容,因为还没有注销。

DELETE TD 
FROM #TestData TD 
INNER JOIN 
(
SELECT a.Name, a.ID, a.Date 
FROM #TestData a 
LEFT JOIN (
      SELECT ID, Date 
      FROM #TestData 
      WHERE Name = 'Login' 
     ) lin 
ON a.ID = lin.ID 
LEFT JOIN (
      SELECT ID, Date 
      FROM #TestData 
      WHERE Name = 'Logout' 
     ) lout 
ON a.ID = lout.ID 
WHERE a.Date BETWEEN lin.Date AND lout.Date 
) b 
ON TD.Date = b.Date 
AND TD.ID = b.ID 
AND TD.Name = b.Name 

后,这样的结果已经运行将是

Name ID Date 
Login 2 2016-06-23 12:15:00.000 
Command 2 2016-06-23 12:25:00.000 
Command 2 2016-06-23 12:35:00.000 

编辑:更新我的回答,以便它现在删除登录/注销命令了。

+0

完美工作! – MisterM

+0

随时upvote任何帮助你的答案。如果解决具体问题,请将其标记为已接受。 –

相关问题