Удалить все строки и оставить последний х слева - PullRequest
2 голосов
/ 22 июля 2010

У меня есть таблица, как

entryid,  roomid
 1           1      
 2          55
 3           1
 4          12
 5           1
 6          44
 7           1
 8           3
 9           1

Теперь я хотел бы удалить ВСЕ записи, где roomid = 1, и сохранить последние 3 из roomid = 1 слева (лучше всего одной командой)

Итак, наконец, entryid: 1 и 3 были удалены, а entryid 6, 7, 9 остается (наверняка, все остальные roomid останутся)

EDIT: Спасибо за помощь. Ниже я добавил собственное решение, для всех желающих

Я задал новый Вопрос как привести это в ОДНУ команду. Вы можете помочь мне там.

Ответы [ 6 ]

2 голосов
/ 22 июля 2010

DELETE поддерживает предложения ORDER BY и LIMIT, поэтому это возможно.Однако из-за ссылочных ограничений DELETE и параметров LIMIT вам нужно два запроса.

SELECT COUNT(*) AS total FROM table  WHERE roomid = 1;
-- run only if count is > 3
DELETE FROM table WHERE roomid = 1 LIMIT total - 3;

Обратите внимание, что для этого, вероятно, потребуется технология-посредник.Я показал запросы для справки.

1 голос
/ 22 июля 2010
SET @deleting = (SELECT COUNT(*) FROM tbl WHERE roomid = 1) - 3;
-- run only if @deleting is > 0
PREPARE stmt FROM 'DELETE FROM tbl WHERE roomid = 1 ORDER BY entryid LIMIT ?';
EXECUTE stmt USING @deleting;
1 голос
/ 22 июля 2010

Вы можете хранить идентификаторы лишних комнат во временной таблице и удалять на основании этого:

create temporary table tmpTable (id int);

insert  tmpTable
        (id)
select  id
from    YourTable yt
where   roomid = 1
        and 3 <=
        (
        select  count(*)
        from    YourTable yt2
        where   yt2.roomid = yt.roomid
                and yt2.id > yt.id
        );

delete  
from    YourTable
where   ID in (select id from tmpTable);    

В результате:

ID  roomid
2   55
4   12
5   44
6   1
7   1
8   3
9   1
0 голосов
/ 23 июля 2010

Спасибо за вашу помощь. Я взял их все вместе и теперь использую это решение :). Для меня этот шаг закрыт.Спасибо.

// Delete older comments from room 1 (keep last 3 left)
// Step 1:
$sql_com = "SELECT id FROM `mytable` WHERE roomid = '1'";
$result = mysql_query ($sql_com); $num_rows = mysql_num_rows($result);       

// Step 2:
if ($num_rows > 3) {
  $sql_com = "SELECT id FROM `mytable` WHERE roomid = '1' ORDER BY id DESC LIMIT 3,1";  
  $result = mysql_query ($sql_com);
  $row = mysql_fetch_array($result, MYSQL_NUM);
}

// Step 3:  
$sql_com = "DELETE FROM `mytable` WHERE roomid = '1' AND id < ".$row[0];
$result = mysql_query ($sql_com);
0 голосов
/ 22 июля 2010

T-SQL парень здесь, но может t-sql сделать:

SELECT
    *
FROM 
    TABLE A

    LEFT JOIN (SELECT TOP 3 entryID FROM TABLE WHERE roomID = 1 ORDER BY entryID DESC) B
    ON A.entryID = B.entryID 
WHERE       
    A.roomID = 1 AND
    B.entryID IS NULL

Затем заменить выбор на УДАЛИТЬ СТОЛ ИЗ ...

?

0 голосов
/ 22 июля 2010

Может работать что-то вроде

delete from TABLE 
where roomid=1 
   and entryid not in 
   (select entryid from TABLE where roomid=1 order by entryid desc limit 0, 3)

.

...