Received: from localhost (unknown [200.46.208.211]) by mail.postgresql.org (Postfix) with ESMTP id 937DE634162 for ; Thu, 29 Oct 2009 15:39:25 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by localhost (mx1.hub.org [200.46.208.211]) (amavisd-maia, port 10024) with ESMTP id 41393-07 for ; Thu, 29 Oct 2009 18:39:09 +0000 (UTC) X-Greylist: delayed 00:09:31.862905 by SQLgrey-1.7.6 Received: from mail.fmed.uba.ar (mail.fmed.uba.ar [157.92.152.1]) by mail.postgresql.org (Postfix) with ESMTP id BE020633454 for ; Thu, 29 Oct 2009 15:39:11 -0300 (ADT) Received: from [157.92.152.105] (unknown [157.92.152.105]) by mail.fmed.uba.ar (Postfix) with ESMTP id C714B39C1D9; Thu, 29 Oct 2009 15:38:03 -0200 (ARST) Message-ID: <4AE9DB6C.6000203@fmed.uba.ar> Date: Thu, 29 Oct 2009 15:14:04 -0300 From: Gerardo Herzig User-Agent: Thunderbird 2.0.0.6 (X11/20070801) MIME-Version: 1.0 To: Grant Masan CC: pgsql-sql@postgresql.org Subject: Re: slow count(CASE) query References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-0.73 tagged_above=-10 required=5 tests=AWL=-0.731, BAYES_50=0.001 X-Spam-Level: X-Archive-Number: 200910/139 X-Sequence-Number: 33338 Grant Masan wrote: > Hi all, > > I have this kind of query that I need to do, yes my query is giving right > answers now but it is long and slow. I am now asking you that if > you have another solution for my query to make that more smarter ! Hope you > can help me with this ! > > > select '000100' as length, sum(ship1) as ship1 ,sum(ship2) as > ship2,sum(ship3) as ship3,sum(ship4) as ship4,sum(ship5) as ship5 FROM > (select > count(CASE WHEN (type between 40 and 49) THEN 1 ELSE NULL END) as ship1, > count(CASE WHEN (type between 60 and 69) THEN 1 ELSE NULL END) as ship2, > count(CASE WHEN (type between 70 and 79) THEN 1 ELSE NULL END) as ship3, > count(CASE WHEN (type between 80 and 89) THEN 1 ELSE NULL END) as ship4, > count(CASE WHEN (type >90) THEN 1 ELSE NULL END) as ship5 > FROM school_proj_boat where length <100 > GROUP BY type > ORDER BY type) as koo > > UNION ALL > > select '100200' as length, sum(ship1) as ship1 ,sum(ship2) as > ship2,sum(ship3) as ship3,sum(ship4) as ship4,sum(ship5) as ship5 FROM > (select > count(CASE WHEN (type between 40 and 49) THEN 1 ELSE NULL END) as ship1, > count(CASE WHEN (type between 60 and 69) THEN 1 ELSE NULL END) as ship2, > count(CASE WHEN (type between 70 and 79) THEN 1 ELSE NULL END) as ship3, > count(CASE WHEN (type between 80 and 89) THEN 1 ELSE NULL END) as ship4, > count(CASE WHEN (type >90) THEN 1 ELSE NULL END) as ship5 > FROM school_proj_boat where length between 100 and 200 > GROUP BY type > ORDER BY type) as koo > > UNION ALL > > select '200300' as length, sum(ship1) as ship1 ,sum(ship2) as > ship2,sum(ship3) as ship3,sum(ship4) as ship4,sum(ship5) as ship5 FROM > (select > count(CASE WHEN (type between 40 and 49) THEN 1 ELSE NULL END) as ship1, > count(CASE WHEN (type between 60 and 69) THEN 1 ELSE NULL END) as ship2, > count(CASE WHEN (type between 70 and 79) THEN 1 ELSE NULL END) as ship3, > count(CASE WHEN (type between 80 and 89) THEN 1 ELSE NULL END) as ship4, > count(CASE WHEN (type >90) THEN 1 ELSE NULL END) as ship5 > FROM school_proj_boat where length between 200 and 300 > GROUP BY type > ORDER BY type) as koo > > UNION ALL > > select '300999' as length, sum(ship1) as ship1 ,sum(ship2) as > ship2,sum(ship3) as ship3,sum(ship4) as ship4,sum(ship5) as ship5 FROM > (select > count(CASE WHEN (type between 40 and 49) THEN 1 ELSE NULL END) as ship1, > count(CASE WHEN (type between 60 and 69) THEN 1 ELSE NULL END) as ship2, > count(CASE WHEN (type between 70 and 79) THEN 1 ELSE NULL END) as ship3, > count(CASE WHEN (type between 80 and 89) THEN 1 ELSE NULL END) as ship4, > count(CASE WHEN (type >90) THEN 1 ELSE NULL END) as ship5 > FROM school_proj_boat where length >300 > GROUP BY type > ORDER BY type) as koo > Well, it looks like this will read school_proj_boat 4 times. What about 1) A plsql function that iterates *one time* on school_proj_boat, with a nested CASE, or a par of IF's 2) Could be a good place for using window functions http://www.postgresql.org/docs/current/static/tutorial-window.html HTH Gerardo