2016-06-23 52 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任何幫助你的答案。如果解決具體問題,請將其標記爲已接受。 –