2017-08-17 169 views
-1

我有一個包含約200個不同ID的表格。每個ID在不同的時間戳記錄中記錄了大約100倍的數據。我想要爲每個ID分別刪除比該特定ID的最年輕記錄早2天的記錄。 又名,我想爲每個ID至少2天的列表。有些可能會達到CURRENTDATE,其他列表可能是2天,從上個月開始。每個ID刪除比最新記錄舊2天的記錄

將這項工作?:

> DELETE FROM loggingTable WHERE (DATE_SUB(MAX(T_log),INTERVAL 48 HOUR)> T_log) GROUP BY ID 

我不想刪除我的數據....

+2

_「我不想刪除我的數據....」_ - 然後創建一個_copy_,然後測試... – CBroe

+0

@CBroe。我的意思是:我不想刪除太多的數據,並假設我做了我所期望的。 – drB

+0

然後創建一個可以驗證的仔細測試條件。如果錯誤,請將測試環境中的數據恢復到之前的狀態(您創建備份的狀態),然後重試。這叫做單元測試你的代碼,並且是編碼的一部分。是的,如果你有經驗的話,你可能會事先確定某個特定的代碼只會通過查看它的工作,但通常這個技能通過大量的測試和試驗和錯誤。由於我們無法看到您的數據,所以很難知道您的查詢是否可以在其上運行,無論如何 – ADyson

回答

0

當你不想意外刪除你的數據,接近在這個問題以下方式(從最壞到最佳):

  1. 創建您的數據的副本並在其上進行工作。
  2. 在交易中進行操作。這將工作像

    START TRANSACTION; 
    DELETE ...; 
    SELECT ...; /* check if everything worked as expected*/ 
    /*if yes...*/ 
    COMMIT; /* this writes your changes on disk */ 
    /*if not, don't do a commit, but instead...*/ 
    ROLLBACK; /* this undoes all the statements in the transaction */ 
    
  3. 第一寫下您DELETE語句作爲SELECT聲明。然後檢查將被刪除的內容。如果沒有問題,請將其轉換爲DELETE聲明(如果願意,可將此方法與上面的第2點結合使用)。比如像下面這樣:

    SELECT 
    * 
    FROM loggingTable lt 
    JOIN (SELECT ID, MAX(T_log)AS max_log FROM loggingTable GROUP BY ID) AS m ON lt.ID = m.ID 
    WHERE lt.T_log < m.max_log - INTERVAL 2 DAY; 
    

    如果看起來不錯:

    DELETE lt.* 
    FROM loggingTable lt 
    JOIN (SELECT ID, MAX(T_log)AS max_log FROM loggingTable GROUP BY ID) AS m ON lt.ID = m.ID 
    WHERE lt.T_log < m.max_log - INTERVAL 2 DAY; 
    

當然,你可以結合方法2和3 1以及;-)

一些附加解釋:我將查詢加入表格的原因是,您不能在WHERE子句中使用聚合函數(如MAX())。 SQL語句進行評估是這樣的:

  1. FROM
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. ORDER BY
  6. 選擇

因爲where子句之前評估group by子句中,您無法訪問聚合te功能在那裏。它們與group by子句一起引入。

+0

謝謝,我明白now.lt.T_log指向原始表,而m.max_log指向JOIN。按ID分組。這就是我一直在尋找的。 – drB