2011-11-22 93 views
4

考慮下表:如何刪除符合條件的記錄,並保留50?

CREATE TABLE `prize` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `prize_details_id` bigint(20) NOT NULL, 
    `status` tinyint(4) DEFAULT '0', 
    `available_at` datetime DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `prize_details_id_idx` (`prize_details_id`), 
    KEY `status_idx` (`status`), 
    KEY `available_at_idx` (`available_at`), 
    CONSTRAINT `prize_prize_details_id_prize_detail_id` FOREIGN KEY (`prize_details_id`) REFERENCES `prize_detail` (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=1611419 DEFAULT CHARSET=latin1; 

我希望做的是刪除n記錄,其中n是匹配的記錄總數的條件少20.表是相當大(大於1m記錄)。

該條件是一個複雜的情況,涉及對頻繁變化的數據進行相對日期查詢,並且還涉及其他幾個表上的聯接,因此首先選擇與條件匹配的數量,然後刪除少於20個的isn據我所知,我不會工作。

的條件是所有的以下內容:

  • prize_details_idx(需要幾個不同的ID運行相同的查詢)
  • available_at是空
  • prize_id沒有在另一個存在表
  • status1
  • tier(onth Èprize_detail表)高於y
+0

所以,最終是最後的記錄保持20最新(即匹配所有其他標準)根據到某個日期?最高?是什麼讓這些最後的特殊? – MPelletier

回答

2

也許是這樣的:

  • 創建臨時表_TMP(ID INT AUTO_INCREMENT,prize_id INT)
  • 選擇匹配獎ID添加到該臨時表
  • 從ID中刪除(從_tmp其中id> = 20選擇prize_id)
+0

好主意,我總是忘記臨時表。將嘗試並更新 – BenLanc

+0

這和@ newtover的答案在下面爲我做了這份工作。這非常慢(約15分鐘),但最終完成了這項工作。 – BenLanc

0
DELETE FROM prize 
WHERE 
    id IN(--Some query--) AND 
    id NOT IN(SELECT id FROM --Some query-- ORDER BY --some column-- LIMIT 20) 

凡識別順序「最後的」 20行

+1

我想他想刪除除最後20個之外的所有內容......不是你的查詢刪除了前20個嗎? –

+0

MySQL不支持TOP。 – BenLanc

+0

@MJJamin好吧,不知道那是尷尬的 – Magnus

1

一個可能的提示:

mysql> 
mysql> CREATE TABLE test (
    -> id SMALLINT unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY 
    ->) ENGINE=InnoDB; 
Query OK, 0 rows affected (0.02 sec) 

mysql> INSERT INTO test() VALUES 
    -> (),(),(),(),(),(),(),(),(),(), 
    -> (),(),(),(),(),(),(),(),(),(), 
    -> (),(),(),(),(),(),(),(),(),(); 
Query OK, 30 rows affected (0.01 sec) 
Records: 30 Duplicates: 0 Warnings: 0 

mysql> DELETE FROM t USING 
    -> test t JOIN (
    ->  SELECT id 
    ->  FROM (
    ->   SELECT id 
    ->   FROM test 
    ->   ORDER BY id DESC 
    ->   LIMIT 20, 1000 
    -> ) as ids) as ids ON t.id = ids.id; 
Query OK, 10 rows affected (0.01 sec) 

mysql> SELECT * FROM test; 
+----+ 
| id | 
+----+ 
| 11 | 
| 12 | 
| 13 | 
| 14 | 
| 15 | 
| 16 | 
| 17 | 
| 18 | 
| 19 | 
| 20 | 
| 21 | 
| 22 | 
| 23 | 
| 24 | 
| 25 | 
| 26 | 
| 27 | 
| 28 | 
| 29 | 
| 30 | 
+----+ 
20 rows in set (0.00 sec)