Как удалить запись из таблицы, если ее количество> 5 - PullRequest
0 голосов
/ 18 мая 2018

У меня есть следующая таблица:

id  systemid    value
1      1           0
2      1           1
3      1           3
4      1           4
6      1           9
8      1           10
9      1           11
10     1           12

Теперь у меня есть 8 записей systemid = 1, поэтому теперь я хочу сохранить только последние 3 записи (в порядке убывания) и удалить более старые записи, чьи systemid=1

Я хочу вывод, например:

id    systemid    value
 8     1            10
 9     1            11
 10    1            12

Я просто хочу удалить старые записи systemid = 1, только если их количество> 5 и сохранить последние 3 записи.

Какя могу сделать это в запросе?

Ответы [ 4 ]

0 голосов
/ 18 мая 2018

Если у вас не всегда есть 8 записей, и вы хотите выбрать последние 3 записи из таблицы, где systemid = 1, сколько бы записей не было, хороший способ сделать это - использовать селектор IN в вашем операторе SQL.

Было бы хорошо, если бы вы могли сделать это, просто используя оператор

SELECT * FROM mytable WHERE id IN (SELECT id FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3)

Однако это еще не поддерживается в MySQL, и если вы попробуете это, вы получите ошибку типа

...doesn't yet support 'LIMIT & IN/ALL/SOME subquery'

Таким образом, вам нужен обходной путь следующим образом (используя SELECT для проверки):

SET @myvar := (SELECT GROUP_CONCAT(id SEPARATOR ',') AS myval FROM (SELECT * FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3 ) A GROUP BY A.systemid);
SELECT * FROM mytable WHERE FIND_IN_SET(id,@myvar);

Способ, которым это работает (первая строка), состоит в том, чтобы установить переменную с именем @myvar, которая будет содержатьпоследние 3 значения в виде строки, разделенной запятыми, если значения id.В вашем случае

9,8,10

Затем выберите строки, в которых 'id' находится в этой строке.

Замените 'SELECT *' на 'DELETE FROM', чтобы завершить результат, чтобы ваш запросбудет

SET @myvar := (SELECT GROUP_CONCAT(id SEPARATOR ',') AS myval FROM (SELECT * FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3 ) A GROUP BY A.systemid);
DELETE FROM mytable WHERE NOT FIND_IN_SET(id,@myvar);

Я надеюсь, что это поможет.

0 голосов
/ 18 мая 2018

Попробуйте сохранить последние три записи, у которых system_id равен 1, а число больше 5:

DELETE FROM <table_name> WHERE system_id = 1 AND value > 5 ORDER BY id DESC LIMIT 3

0 голосов
/ 18 мая 2018

Это будет очень длинный запрос.Вам нужно для каждого system_id, имеющего более 5 записей, вы хотите удалить запись с рейтингом меньше 3.

Я собираюсь разделить запросы и использовать имена для них в конце.

1_ rating_query: аббревиатура RQ

В mysql нет rownum или чего-то подобного, надеюсь, что этот запрос вернет записи, ранжированные от ghe от первого до последнего.

       SELECT 
               @rank := @rank + 1 as rank, 
               id, 
               system_id,
               value
       FROM table_name, (select @rank:=0) as rt
       order by system_id, value desc

это будет ранжировать каждую запись в вашей таблице, и главное преимущество заключается в том, что запись с одинаковым system_id будет следовать друг за другом в порядке убывания

            system_id       value      rank
               1.                     10.         1

                1.                     9.           2

                1.                     7.           3

                1.                     5.           4

                1.                     3.            5

                1.                      2.           6

                2.                    12.          7

                2.                    10.          8

                3.                     11.         9
                ........
                ......
                 3.                     1.          15

В этом примере для system_id1 нам нужно сохранить только три первых (1,2,3) записи одинаково для system_id 3 (9,10,11)

2_ filter_query.Abriviation: FQ. Поскольку вы хотите удалить на основе счетчика 5, нам нужен этот дополнительный запрос

        SELECT
                 system_id
        FROM table_name
        GROUP BY system_id 
        having count(*) > 5

результат:

                     system_id
                        1
                        3

4_ third_quervrivion: RQD

aзапрос, чтобы узнать, с какого ранга мы должны начать, действительно удаляем для каждого system_id в mysql, нам нужно переписать первый запрос снова, но здесь я собираюсь использовать Abriviation, чтобы сохранить ответ коротким.

         SELECT 
               system_id,
               min_rank + 3  from_rank
        FROM (
               SELECT
                      RQ2.system_id,
                      min(RQ2.rank) as  min_rank
              FROM (rank_query) RQ2
              GROUP BY system_id) RS

, поэтому для того же примера мы получим этот результат

         system_id.    from_rank 
            1.                     4
            2.                     9    -- this record will be removed by the filter_query
            3.                     12

FINAL QUERY:

, поэтому нам нужно удалить запись, которая существует в запросе фильтраи рейтинг больше, чем from_rank.

        DELETE FROM table_name WHERE 
              id in (
                 SELECT
                     RQ.id
                 FROM
                            rank_query RQ INNER JOIN filter_query FQ ON rq.system_id = FQ.system_id
                                                       INNER JOIN third_query RQD ON RQ.rank >= RQD.from_rank)

Я надеюсь, что эта идея сработает, извините за любую синтаксическую ошибку, я использовал свой телефон, чтобы ответить мне нравится этот тип запроса

0 голосов
/ 18 мая 2018

Вы можете указать смещение с ключевым словом LIMIT в своем запросе, чтобы сохранить самые последние 5 строк.Однако, согласно документации MySQL, нет простого способа ограничить смещение до последнего;вместо этого они предлагают следующее:

Чтобы извлечь все строки от определенного смещения до конца набора результатов, вы можете использовать некоторое большое число для второго параметра.

Таким образом, этот SQL должен выполнить свою задачу:

DELETE FROM table, где systemid = 1 ORDER BY value DESC LIMIT 5,45484848

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...