SQL УДАЛИТЬ все строки кроме последних N строк для каждого уникального значения - PullRequest
4 голосов
/ 10 февраля 2011

Вот сложный вопрос: как бы удалить все, кроме последних, скажем, 3 строки, для каждого уникального значения в отдельном поле?

Вот визуальное представление о проблеме:

id | otherfield
---------------
 1 | apple      <- DELETE
 2 | banana     <- KEEP
 3 | apple      <- DELETE
 4 | apple      <- KEEP
 5 | carrot     <- KEEP
 6 | apple      <- KEEP
 7 | apple      <- KEEP
 8 | banana     <- KEEP

Как бы я сделал это в SQL?

Ответы [ 2 ]

1 голос
/ 10 февраля 2011
Delete MyTable
Where Id In (
            Select Id
            From    (
                    Select Id
                        , (Select COUNT(*)
                            From MyTable As T2
                            Where T2.OtherField = T.OtherField
                                And T2.Id > T.Id) As Rnk
                    From MyTable As T
                    ) As Z
            Where Z.Rnk > 2     
            )   

Другая версия, которая может быть немного быстрее:

Delete MyTable
Where Id In (
            Select T.Id
            From MyTable As T
                Left Join MyTable As T2
                    On T2.OtherField = T.OtherField
                        And T2.Id > T.Id
            Group By T.Id
            Having Count(T2.Id) > 2
            )
1 голос
/ 10 февраля 2011

Не проверено, но что-то в этом роде может работать:

DELETE t.*
FROM table t JOIN (
    SELECT id
        @rowNum := IF(@otherfield <> otherfield, 1, @rowNum + 1) rn,
        @otherfield := otherfield otherfield
    FROM (
        SELECT id, otherfield
        FROM table
        ORDER BY otherfield, id DESC
    ) t, (SELECT @otherfield := NULL, @rowNum := -1) dm
) rs ON t.id = rs.id
WHERE rs.rn > 3
...