Received: from localhost (unknown [200.46.204.184]) by postgresql.org (Postfix) with ESMTP id 836632E32A2 for ; Tue, 8 Jan 2008 10:24:34 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.184]) (amavisd-maia, port 10024) with ESMTP id 20571-05 for ; Tue, 8 Jan 2008 10:24:15 -0400 (AST) Received: from py-out-1112.google.com (py-out-1112.google.com [64.233.166.180]) by postgresql.org (Postfix) with ESMTP id A52C62E316A for ; Tue, 8 Jan 2008 10:24:23 -0400 (AST) Received: by py-out-1112.google.com with SMTP id d37so5778337pye.29 for ; Tue, 08 Jan 2008 06:24:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; bh=R0hm46U+Gkwd9veThjfz+6AjC/ZAr7sMparARN5RftQ=; b=O1Ilg7mR0+dU2guULlveZQYIIJeR2uywJzp8XMAykrfACDKSKb5TDbl36O8DYJCpkHDq6bwc3eMtFQwXz/584NUgbtIZVxkbavPhwYEiId6RckgSolErKsMDN23J5JF0BHtISGkgZUmcMk4QK0zJ/vdt0V1QMZBt7YmzqHZY3f0= DomainKey-Signature: a=rsa-sha1; c=nofws; d=googlemail.com; s=gamma; h=message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; b=HjSF8x1JRnx+1oPe9c1DYxIs23I/saaMfe95l76bWTQ4v/PZynZJlpuxgFM1YMujActDG8M4PPRsQsXGhtde9+9p7QcRBz60yR54f4gGglgVeER+KE+uqBieSY0PfA3sJMiE4PnoUFuJ5GugX9bjIPopmYWv+iIW4PqMcVW5BY8= Received: by 10.35.30.8 with SMTP id h8mr3813725pyj.55.1199802262282; Tue, 08 Jan 2008 06:24:22 -0800 (PST) Received: by 10.35.82.11 with HTTP; Tue, 8 Jan 2008 06:24:22 -0800 (PST) Message-ID: Date: Tue, 8 Jan 2008 14:24:22 +0000 From: "Jamie Tufnell" To: pgsql-sql@postgresql.org Subject: How to keep at-most N rows per group? periodic DELETEs or constraints or..? MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200801/44 X-Sequence-Number: 29897 Hi, I have a table that stores per-user histories of recently viewed items and I'd like to limit the amount of history items to <= 50 per user. I'm considering doing this with a query run from cron every so often but I'm not happy with what I've come up with so far, and since it's a quite active table I thought I'd ask here to see if there's a more efficient way. Right now the table structure is as follows... user_item_history: id (PK), user_id (FK), item_id (FK), timestamp For user_ids that have more than 50 rows, I want to keep the most recent 50 and delete the rest. The most obvious way of doing this for me is: -- -- Get the user_ids with 50 or more history entries like this -- SELECT user_id, count(*) FROM user_scene_history GROUP BY user_id HAVING count(*) > 50; -- -- Then iterate the ids above (_user_id) -- DELETE FROM user_scene_history WHERE user_id = _user_id AND id NOT IN ( SELECT id FROM user_scene_history WHERE user_id = _user_id ORDER BY timestamp DESC LIMIT 50); I've left out the simple logic tying the above two queries together for clarity.. I haven't actually tested this but while I assume it would work I imagine there is a neater and possibly more efficient way of attacking this. I'm also open to different approaches of limiting the user's history too ... perhaps with table constraints so they can simply never exceed 50 entries? But I'm not sure how to do this.. Any help would be greatly appreciated.. Thanks, Jamie