SQL:“「”」まで選択します
-
08-07-2019 - |
質問
合計額に達するまで選択する方法を探しています。
マイ" documents"テーブルには" tag_id
"および" size
"フィールド。
tag_id = 26
のすべてのドキュメントを選択したいが、600単位のサイズしか処理できないことがわかっている。したがって、最初の10個が既に>に追加されていることがわかっていたとしても、100個のドキュメントを選択して90個を破棄しても意味がありません。 600ユニット。
したがって、目標は、大量のデータを戻して、ほとんどのデータを破棄するときに解析することではありません。
...しかし、このアプリにカーソルでの作業を導入することも避けたいです。
mysqlを使用しています。
解決
最大単位を合計するときに、他のレコードよりも優先するレコードを注文する方法が必要です。それ以外の場合、合計で最大600件のレコードセットを保持していることをどのように確認しますか?
SELECT d.id, d.size, d.date_created
FROM documents d
INNER JOIN documents d2 ON d2.tag_id=d.tag_id AND d2.date_created >= d.date_created
WHERE d.tag_id=26
GROUP BY d.id, d.size, d.date_created
HAVING sum(d2.size) <= 600
ORDER BY d.date_created DESC
これは開始するための基本的なクエリにすぎず、まだ解決すべき問題がいくつかあります:
- &lt; = 600で停止するため、ほとんどの場合、サイズ制限を正確に埋めることはできません。これは、もう1つのレコードを許可するように微調整する必要がある場合があることを意味します。たとえば、最初のレコードが&gt;の場合600クエリは何も返さないため、問題になる可能性があります。
- 上限以下に収まる可能性がある追加の小さいレコードを後でチェックすることはありません。
- 同じdate_created値を持つレコードは、あちこちで「二重にカウント」されている可能性があります。
編集
日付でソートしているという情報を追加したため、更新されました。
他のヒント
これは非常に効率的ではありませんが、カーソルを回避します(ドキュメントテーブルにもシリアルID列があると仮定します):
select a.id, (select sum(b.size) from documents b where b.id <= a.id and b.tag_id = 26)
from documents a
where a.tag_id = 26
order by a.id
また、これはpgsqlで行われたため、この正確な構文がmysqlで機能するかどうかはわかりません。
次に、合計&gt;を持つものを探す別のクエリでこれをラップできます。 600(合計列に名前を付ける必要があります)、最初のIDを取得します。次に、以下のすべてのIDを処理し、そのIDを含めます。
まずドキュメントをテーブル変数に保存し、取得したい順に並べ替えてから、各行を累積値で更新して選択できるようにする必要があります。
declare @documents_temp table (
tag_id int,
size int,
cumulative_size int null)
insert into @documents_temp
select tag_id, size, size from documents order by tag_id
update @documents_temp d set d.cumulative_size = d.size +
(select top 1 cumulative_size from @documents_temp
where tag_id < d.tag_id order by tag_id desc)
select tag_id, size from @documents_temp where cumulative_size <= 600
価値があるかどうかわからない。