X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (neptune.hub.org [200.46.204.2]) by svr1.postgresql.org (Postfix) with ESMTP id 9AF92D1DBF7 for ; Fri, 12 Dec 2003 00:47:52 +0000 (GMT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (neptune.hub.org [200.46.204.2]) (amavisd-new, port 10024) with ESMTP id 42168-04 for ; Thu, 11 Dec 2003 20:47:24 -0400 (AST) Received: from megazone.bigpanda.com (megazone.bigpanda.com [64.147.171.210]) by svr1.postgresql.org (Postfix) with ESMTP id C5887D1B456 for ; Thu, 11 Dec 2003 20:47:20 -0400 (AST) Received: by megazone.bigpanda.com (Postfix, from userid 1001) id 5826735444; Thu, 11 Dec 2003 16:47:23 -0800 (PST) Received: from localhost (localhost [127.0.0.1]) by megazone.bigpanda.com (Postfix) with ESMTP id 54981353D7; Thu, 11 Dec 2003 16:47:23 -0800 (PST) Date: Thu, 11 Dec 2003 16:47:23 -0800 (PST) From: Stephan Szabo To: "Marc G. Fournier" Cc: pgsql-sql@postgresql.org Subject: Re: simple LEFT JOIN giving wrong results ... In-Reply-To: <20031211165902.I17041@ganymede.hub.org> Message-ID: <20031211163626.N45954@megazone.bigpanda.com> References: <20031211165902.I17041@ganymede.hub.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Virus-Scanned: by amavisd-new at postgresql.org X-Archive-Number: 200312/93 X-Sequence-Number: 16259 On Thu, 11 Dec 2003, Marc G. Fournier wrote: > > I've got to be missing something obvious here ... I have two tables, on > containing traffic stats, the other disk usage ... I want to do a JOIN in > one query to give me the sum of traffic and average of storage ... > seperately, the results are right .. put together, traffic values are way > off, while storage is still correct ... > > So, I'm doing my LEFT JOIN wrong *somehow*, but its eluding me as to > what/how .. :( > > ams=# select ct.ip_id, sum(ct.bytes) as traffic, > avg(cs.bytes)::bigint as storage > from company_00186.traffic ct > left join company_00186.storage cs ON ( ct.ip_id = cs.ip_id AND > month_trunc(cs.runtime) = '2003-12-01') > where month_trunc(ct.runtime) = '2003-12-01' group by ct.ip_id; If there are multiple cs rows that match a particular ct row with those constraints you're going to be getting a multiple of the ct.bytes value with sum because you're going to have an extra ct.bytes for each matching cs row. If you had two traffic rows with ip_id 1 with bytes 10 and 5 and two storage rows with ip_id 1 with bytes 5 and 3 (and assuming that they both are in the right month), the join should give you a set like: ((ip_id=1, ct.bytes=10, cs.bytes=5), (ip_id=1, ct.bytes=10, cs.bytes=3), (ip_id=1, ct.bytes=5, cs.bytes=5), (ip_id=1, ct.bytes=5, cs.bytes=3)) I don't think a join between the two tables is what you really want. Maybe a join between the two group by querys, something like: select ip_id, traffic, storage from (select ip_id, sum(ct.bytes) as traffic from company_00186.traffic ct where month_trunc(runtime)='2003-12-01') a left outer join (select ip_id, avg(ct.bytes) as storage from company_00186.storage ct where month_trunc(runtime)='2003-12-01') b using (ip_id);