2011-12-14 13 views
0

基本的に私は添付ファイルを持つテーブルを持っています。シンプルなテーブル:ID、名前、サイズ、アップロード日。私は合計で2 GB未満の最後のx行を取得したい。特定の条件がMySQLで満たされるまでの行の取得

したがって、ファイルサイズが2GBになるまで、アップロードされた日付のDESC順ですべての行を収集し、残りの部分を削除します。

実際、私はその逆が必要です。だから、私は最初の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 

削除するには、添付ファイルを選択します。

DISCLAIMER標準のsqlでは、n行の表の場合はΩ(n^2)最悪のため、遅いです。 @ 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

+0

@AWebDevDuh hah、そうだよ:)編集 – soulcheck

+0

これは、巨大なデカルト製品で終わることになるだろう。 – newtover

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の代わりにテーブルが必要です。

+0

これは近いと思いますが、行1から行Zまで繰り返す必要があるのでUNIONを使用すべきではありません。合計カウンターとして@合計は、HAVINGを課す? – ajreal

+0

@arjreal、UNIONを使用してはいけない理由を理解できませんでした(私は例の表をエミュレートするために使用しました)。 HAVINGに関しては、注文が適用された後で状態がチェックされていることに気づいていません。そう、少なくとももっと読みやすく、より効率的になるでしょう。 – newtover

+0

あなたが誤解していると思うのは、一致する特定の行(あなたの答えでは4)だけがあると仮定していますが、実際の行は不明です。 UNIONを取り除くには、カウンター+ HAVINGを使用してフィルターをかけることができます。 – ajreal

関連する問題