在MySQL中获取行直到满足某个条件

时间:2011-12-14 00:14:20

标签: mysql group-by limit aggregate-functions

基本上我有一张附有附件的桌子。简单表:ID,名称,大小和UploadedDate。我想得到总共最后x行,小于2 GB。

因此,收集所有行的DESDB顺序为UploadedDate,直到我有2GB的文件总大小,然后消除其余的。

实际上我需要反过来。因此,我需要获得不属于前2 GB的所有附件。我有MySQL的先进经验,但现在看起来我有一个空白。我不知道该搜索什么。

3 个答案:

答案 0 :(得分:1)

一个hacky提示:

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应该有你的桌子。

答案 1 :(得分:0)

您可以通过为每个字段的数据类型添加空间要求来计算每行的可能大小,然后使用它来计算出2 GB的行数。

答案 2 :(得分:0)

您可以使用此查询:

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

选择要删除的附件。

免责声明虽然它是标准的sql但它会很慢,因为它是具有n行的表的最坏情况Ω(n ^ 2)。使用@newtover的解决方案。

在这种情况下,通过使用存储过程并在总结其大小的同时循环遍历附件可能会更好。

对于丢失的postgres灵魂,这里的解决方案相当于@ newtover's但使用了窗口函数:

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