Received: from localhost (maia-3.hub.org [200.46.204.184]) by postgresql.org (Postfix) with ESMTP id 9D37B9F9A0A for ; Tue, 21 Aug 2007 18:16:42 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.184]) (amavisd-maia, port 10024) with ESMTP id 03859-09 for ; Tue, 21 Aug 2007 18:16:33 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from mtai03.charter.net (mtai03.charter.net [209.225.8.183]) by postgresql.org (Postfix) with ESMTP id 2084B9F9942 for ; Tue, 21 Aug 2007 18:16:38 -0300 (ADT) Received: from aa02.charter.net ([10.20.200.154]) by mtai03.charter.net (InterMail vM.7.08.02.00 201-2186-121-20061213) with ESMTP id <20070821211636.YCIX21729.mtai03.charter.net@aa02.charter.net>; Tue, 21 Aug 2007 17:16:36 -0400 Received: from [10.0.1.2] (really [66.188.165.91]) by aa02.charter.net with ESMTP id <20070821211636.SACH26124.aa02.charter.net@[10.0.1.2]>; Tue, 21 Aug 2007 17:16:36 -0400 In-Reply-To: <5C7C0B0734F87445AFC8B63EDCC4901E015ED7EE@CORPUSMX60C.corp.emc.com> References: <5C7C0B0734F87445AFC8B63EDCC4901E015ED7EE@CORPUSMX60C.corp.emc.com> Mime-Version: 1.0 (Apple Message framework v752.2) Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed Message-Id: <3D88F0CD-4914-460C-96D8-A7E06CC29C83@seespotcode.net> Cc: Content-Transfer-Encoding: 7bit From: Michael Glaesemann Subject: Re: Join question Date: Tue, 21 Aug 2007 16:16:35 -0500 To: tyrrill_ed@emc.com X-Mailer: Apple Mail (2.752.2) X-Chzlrs: 0 X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200708/172 X-Sequence-Number: 29110 On Aug 21, 2007, at 12:48 , tyrrill_ed@emc.com wrote: > SELECT a.x, max(b.x) FROM a, b, c WHERE a.a_id = c.a_id AND b.b_id = > c.b_id GROUP by a.x; Shouldn't affect performance, but another way to write this which you may find more readable is to list your join conditions with the joins rather than grouping them all in the WHERE clause: SELECT a.x, max(b.x) FROM a JOIN c USING (a_id) JOIN b USING (b_id) GROUP BY a.x; You can also write this using NATURAL JOIN which joins on like-named columns. SELECT a.x, max(b.x) FROM a NATURAL JOIN c JOIN b USING (b_id) GROUP BY a.x; You can't use NATURAL JOIN to join b because you've got columns named x in both a and b that you're *not* joining on. Another nice thing about the USING and NATURAL JOIN syntax is that the result includes only one column for the joined columns, rather than two. In this case, there would be only one b_id and one a_id column in the result set. Using ON or putting the join condition in the WHERE clause puts two b_id and two a_id columns in the result set. > Does anyone know a > way I could restructure this query to get only one b for each a in a > faster way? You might want to ask on the pgsql-performance list as well, as people there are generally interested in improving query performance. One thing they'll ask you for is the output of EXPLAIN ANALYZE for your query. Here's an alternative, but I don't know how it'd compare in terms of performance: EXPLAIN ANALYZE SELECT DISTINCT ON (a.x) a.x, b.x FROM a NATURAL JOIN c JOIN b USING (b_id); Give that a shot. (DISTINCT ON is a non-standard PostgreSQL extension, if non-portable syntax is something you're looking to avoid.) EXPLAIN ANALYZE shows you how the planner decided to proceed with the query, which can be useful when comparing alternatives, so you can compare using DISTINCT ON with your own query using max. Hope this helps. Michael Glaesemann grzm seespotcode net