Получение строк, пока не выполнено определенное условие в MySQL - PullRequest
0 голосов
/ 14 декабря 2011

В основном у меня есть таблица с вложениями.Простая таблица: ID, имя, размер и дата загрузки.Я хочу получить последние x строк, которые в сумме не превышают 2 ГБ.

Итак, соберите все строки в порядке DESC UploadedDate, пока у меня не будет 2 ГБ общего размера файлов, а затем удалите остальные.

На самом деле мне нужно обратное.Итак, мне нужно получить все вложения, которые не являются частью первых 2 ГБ.У меня есть опыт работы с MySQL, но сейчас мне кажется, что у меня есть пробел по этому вопросу.Я не знаю, что искать.

Ответы [ 3 ]

1 голос
/ 14 декабря 2011

хакерский намек:

SELECT items.* FROM (
  SELECT 1 as id, 100 as size
  UNION ALL
  SELECT 2 as id, 100 as size
  UNION ALL
  SELECT 3 as id, 100 as size
  UNION ALL
  SELECT 4 as id, 100 as size
  ORDER BY id DESC
) items, (SELECT @total:=0) as init
WHERE (@total:=@total+size)+0 <= 200;


+----+------+
| id | size |
+----+------+
|  4 |  100 |
|  3 |  100 |
+----+------+
2 rows in set (0.00 sec)

UPD

По сути то же самое, но, вероятно, более эффективно:

SELECT items.* FROM (
  SELECT 1 as id, 100 as size
  UNION ALL
  SELECT 2 as id, 100 as size
  UNION ALL
  SELECT 3 as id, 100 as size
  UNION ALL
  SELECT 4 as id, 100 as size
) items, (SELECT @total:=0) as init
HAVING (@total:=@total+size)+0 <= 200
ORDER BY id DESC;

Идея в том, что вместо items должен быть ваш стол.

0 голосов
/ 14 декабря 2011

Вы можете использовать этот запрос:

SELECT t1.ID
FROM attachments t1, attachments t2
WHERE t2.UploadedDate >= t1.UploadedDate
GROUP BY t1.ID
HAVING sum(t2.Size) > 2GB

, чтобы выбрать вложения для удаления.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ в то время как это стандартный sql, он будет медленным, так как это Ω (n ^ 2) худший случай для таблицы с n строками. Используйте решение @ newtover.

В этом случае вам может быть лучше использовать хранимую процедуру и перебирать вложения, суммируя их размеры.

А для потерянных душ postgres вот решение, эквивалентное @ newtover, но использующее оконную функцию:

SELECT outer_t.ID
FROM (
    SELECT t.ID, sum(t.Size) s
OVER (ORDER BY t.UploadedDate DESC)
FROM attachments as t
) as outer_t
WHERE outer_t.s > 2GB
0 голосов
/ 14 декабря 2011

Можно определить возможный размер каждой строки, сложив требования к пространству для типа данных каждого поля, а затем использовать это для определения количества строк 2 ГБ.

...