Received: from localhost (postgresql.org [64.49.215.8]) by postgresql.org (Postfix) with ESMTP id D138F476345 for ; Mon, 13 Jan 2003 14:30:30 -0500 (EST) Received: from anchor-post-39.mail.demon.net (anchor-post-39.mail.demon.net [194.217.242.80]) by postgresql.org (Postfix) with ESMTP id 1A62C4768A2 for ; Mon, 13 Jan 2003 14:30:28 -0500 (EST) Received: from mwynhau.demon.co.uk ([193.237.186.96] helo=mainbox.archonet.com) by anchor-post-39.mail.demon.net with esmtp (Exim 3.36 #2) id 18YAHz-000622-0U; Mon, 13 Jan 2003 19:30:27 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by mainbox.archonet.com (Postfix) with ESMTP id CC9E91781C; Mon, 13 Jan 2003 19:30:25 +0000 (GMT) Received: from archonet.com (localhost.localdomain [127.0.0.1]) by mainbox.archonet.com (Postfix) with SMTP id 362F51781B; Mon, 13 Jan 2003 19:30:25 +0000 (GMT) Received: from 192.168.1.16 (SquirrelMail authenticated user dev) by mainbox.archonet.com with HTTP; Mon, 13 Jan 2003 19:30:25 -0000 (GMT) Message-ID: <3257.192.168.1.16.1042486225.squirrel@mainbox.archonet.com> In-Reply-To: References: <1493.192.168.1.16.1042462021.squirrel@mainbox.archonet.com> Date: Mon, 13 Jan 2003 19:30:25 -0000 (GMT) Subject: Re: Crosstab-style query in pure SQL From: dev@archonet.com To: "Josh Berkus" Cc: dev@archonet.com, pgsql-sql@postgresql.org X-Mailer: SquirrelMail (version 1.3.2) MIME-Version: 1.0 Content-Type: text/plain;charset=iso-8859-1 X-Priority: 3 Importance: Normal X-Virus-Scanned: by AMaViS snapshot-20020531 X-Virus-Scanned: by AMaViS new-20020517 X-Archive-Number: 200301/182 X-Sequence-Number: 11047 > Richard, > >> I have a table containing milestones achieved for projects, marked as >> being in particular quarters. >> >> CREATE TABLE milestones ( >> proj_id int4, >> sortorder SERIAL, >> qtr int4, >> description varchar(200) >> ); >> >> Now I need the milestone descriptions output across the page like: >> proj_id | q1 | q2 | q3 | q4 >> and sorted according to "sortorder". > > Ah! A classic SQL problem. > > Take a look at Joe Celko's "SQL for Smarties": he does a good job of > defining and discussing the three different solutions to the "Crosstab > Query" problem. > > A second method you can use is the subselect method: > > SELECT proj_id, sortorder, qart1.q1, quart2.q2 .... > FROM milestones > LEFT OUTER JOIN ( SELECT proj_id, description as q1 > FROM milestones WHERE qtr = 1) quart1 > ON quart1.proj_id = milestones.proj_id > LEFT OUTER JOIN ( SELECT proj_id, description q2 ... > > However, the above is generally chosen over the CASE statement method > when the crosstab involves multiple tables; in your case, it is not a > performance or similicity gain. Thanks Josh, but that still leaves me with nulls if I join on sortorder too, and duplicates if not (as you imply, since it's equivalent to the CASE option). The problem is that since I defined "sortorder" as a serial, equivalent rows of a specific project don't match across the key. Without calculating a "row_index" based on (proj_id,sortorder) it doesn't look like there's anything to be done without procedural help. Didn't think there was anything simple - my fault for not having common keys to match up output rows - oversimplified the input stage and I'm paying for it on output. - Richard Huxton