![]() |
|
Модераторы: skyboy |
![]()
|
|
| rcdimon |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 766 Регистрация: 12.7.2004 Где: Москва Репутация: нет Всего: 2 |
У меня есть таблица- журнал действий пользователей. Необходимо один раз в сутки исполнять запрос, который будет очищать таблицу, оставляя по 20 последних определенных действий каждого пользователя. Таблица такого вида
id - Номер строки (autoincrement) user_id - Номер пользователя action - Номер действия Надо оставлять действия следующих номеров (250, 255, 257, 306, 310, 322, 350, 354, 551, 553, 562, 563), остальные удалять, даже если они входят в двадцатку последних. Заранее спасибо. |
|||
|
||||
| Akina |
|
|||
|
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 45 Всего: 454 |
То есть должны остаться по 20 записей каждого действия из перечисленных для каждого из пользователей, а остальное в корзину? Мрачный запрос... я бы наоборот, скопировал то, что надо оставить, во временную таблицу, очистил бы рабочую и вернул в неё сохранённые записи.
-------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
| rcdimon |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 766 Регистрация: 12.7.2004 Где: Москва Репутация: нет Всего: 2 |
Ну тогда помоги с запросом, который скопирует нужное )
|
|||
|
||||
| Gluttton |
|
||||
![]() Начинающий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1170 Регистрация: 28.8.2008 Где: Феодосия Репутация: 24 Всего: 54 |
Вот пример некоректного решения, ошибочно построеного на убеждении, что для таблицы никогда не будет применяться запрос на удаление, и автоинкремент можно использовать как "индикатор" последовательности событий.
По хорошему в существующую таблицу необходимо добавить колонку, что то вроде time, которая бы хранила время операции, тогда можно было бы предложить более коректное решение. А если таблица общая (в смысле одна на всех пользователей, а оно судя по всему так и есть), а необходимо выводить последние 20 событий для КАЖДОГО пользователя, то тогда это уже будет несколько другое решение. Добавлено через 6 минут и 16 секунд
Внимательно прочитав вопрос, понял, что не совсем то написал (или совсем не то) Так лучше? -------------------- Слава Україні! |
||||
|
|||||
| Akina |
|
|||
|
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 45 Всего: 454 |
Это неверное решение. Запрос выберет записи указанного типа из 20 последних записей. То есть их ВСЕГО будет не более 20, а скорее всего меньше, если среди последних 20 есть записи другого типа... rcdimon, подходить к запросу можно, скажем, так: сначала надо получить все пары юзер+тип
Далее надо построить запрос, который для каждой группы отсортирует события по уменьшению ID, пронумерует их в группе вычисляемым полем и отберёт те записи, у которых это вычисляемое поле будет не более 20. Можно копировать полученную выборку во временную таблицу, либо модифицировать, отбирая записи с вычисляемым полем более 20 и использовать IDы как условие отбора в запросе на удаление. Но в любом случае это будет монстроидальный запрос, которы будет жеваться сервером долго и нудно. Я же полагаю, что есть смысл пойти по пути создания хранимой процедуры - получив в ней результат вышенаписанного запроса, идём по нему с курсором и выгребаем IDы по условию order by ID DESC limit 20 записей для каждой записи из этого запроса, сваливая их во временную таблицу. После чего заключительным аккордом связываем временную таблицу с основной и выполняем удаление по условию отсутствия ID во временной таблице. В любом случае жутик. ============= Но вообще я бы делал совершенно иначе. Завёл бы поле действительности записи. И каждый раз при внесении в таблицу очередной записи о событии для заданного события и юзера все аналогичные записи кроме последних 20 в этом поле помечал бы крестиком. Оформить лучше всего триггером, чтобы не засорять сами фиксирующие запросы. Тогда очистка таблицы станет делом совершенно тривиальным - просто давим всё, что имет крестик в поле действительности. А если ещё создать табличку, которая установит соответствие между, скажем, типом события и количеством оставляемых непомеченными записей данного события для каждого юзера - процесс руления очисткой станет более гибким и динамичным. Кроме того, нагрузка по очистке таблицы фактически будет размазана по всему периоду её наполнения, что благоприятно скажется на производительности системы. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
| rcdimon |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 766 Регистрация: 12.7.2004 Где: Москва Репутация: нет Всего: 2 |
А, например, вынуть из лога список пользователей, чьи события там присутствуют, а потом программой в цикле для каждого пользователя провети удаления, оставляя последние 20 записей? Долго наверное будет при большом числе пользователей....
|
|||
|
||||
| Gluttton |
|
||||
![]() Начинающий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1170 Регистрация: 28.8.2008 Где: Феодосия Репутация: 24 Всего: 54 |
to Akina
Однозначно согласен Ниже привожу "крокодила" претендующего на звание правильного, но не коректного решения.
-------------------- Слава Україні! |
||||
|
|||||
| rcdimon |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 766 Регистрация: 12.7.2004 Где: Москва Репутация: нет Всего: 2 |
Что некорректного то.. autoincrement каждый следующий всегда больше предыдущего. Удаляй ты записи из таблицы или нет.... Если id у записи больше- однозначно можно сказать, что она была добавлена позже. А поле со временем у меня в таблице есть DATETIME
|
|||
|
||||
| Akina |
|
|||
|
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 45 Всего: 454 |
На более-менее приличной базе от запроса такого рода сервер уйдёт в штопор. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
| rcdimon |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 766 Регистрация: 12.7.2004 Где: Москва Репутация: нет Всего: 2 |
Мне понравилась идея про метку того, что эту запись можно удалять.
Единственное возникла проблема с запросом на установку метки ) Перед записью новой строки в таблицу, запрос находит 20-ую по новизне запись и ставит метку. Запрос который пришел в голову такой
Но мне благополучно выдается ошибка
Добавлено через 2 минуты и 4 секунды а в таком
такая
|
||||||||
|
|||||||||
| Dobermann |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 992 Регистрация: 7.1.2008 Репутация: нет Всего: 0 |
||||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Составление SQL-запросов | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |