2011-12-14 76 views
0

基本上我有一个有附件的表。简单的表格:ID,名称,大小和UploadedDate。我想得到总共最后的x行,小于2 GB。获取行直到在MySQL中满足特定条件为止

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

其实我需要的是相反的。所以,我需要获得所有不属于第一个2 GB的附件。我在MySQL中有丰富的经验,但现在看起来我对此有一个空白。我不知道要搜索什么。

回答

0

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

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^2)最坏的情况下表n行。使用@ newtover的解决方案。

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

而失去的Postgres的灵魂在这里这相当于@ newtover的解决方案,但使用窗口funcion:

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

`HAVING sum(t2.size)> 2GB`不起作用? – ademers 2011-12-14 03:00:57

+0

@AWebDevDuh哈哈,你是对的,它会:)编辑 – soulcheck 2011-12-14 03:09:32

1

哈克提示:

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:[email protected]+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:[email protected]+size)+0 <= 200 
ORDER BY id DESC; 

想法是,而不是items应该有你的表。

相关问题