Received: from maia.hub.org (unknown [200.46.204.183]) by mail.postgresql.org (Postfix) with ESMTP id 1B83D6342D7 for ; Thu, 29 Oct 2009 18:49:34 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 03834-07 for ; Thu, 29 Oct 2009 21:49:26 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-pw0-f44.google.com (mail-pw0-f44.google.com [209.85.160.44]) by mail.postgresql.org (Postfix) with ESMTP id 81704633EF7 for ; Thu, 29 Oct 2009 18:49:24 -0300 (ADT) Received: by pwj8 with SMTP id 8so322327pwj.3 for ; Thu, 29 Oct 2009 14:49:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:cc:subject:references:in-reply-to :content-type:content-transfer-encoding; bh=+AE+973L43xGJm2PAy9/42yQVD/4T0rD6ir4/VqLKZE=; b=hZs9VVNsLVpNFbnObssd1WvuOLyc6Rm/CSeukCLf5oPSB/efNq6q4TNqzlzfaPtvbo aF1aVvYITzUV35Evx7M6A2HswVvuFj62WmHrmDQF7KQnQamVj8PnyGlyAUnKw382q3vc j/lidJX73FnSS5hR7B3nixP4qve8gBRtU+kNM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; b=P4g9ICS3Q6g0+IX44+pd3ahGjV6tDepFTN8iFu3u2cJ4g+JyjiszzaZfjmHUMBETeA kX8A+ew1hccOQevEQvZWG0u/f6Wz1IglJnV8uSNUsdMPTvi8Srf04kYMS/C9k1ZRVEK7 eNbv5H4Vq5bvJEFduGX08fFeKCR4x+DNITCy4= Received: by 10.114.187.7 with SMTP id k7mr411980waf.106.1256852963021; Thu, 29 Oct 2009 14:49:23 -0700 (PDT) Received: from ?172.16.1.239? ([208.187.158.94]) by mx.google.com with ESMTPS id 20sm259306pzk.1.2009.10.29.14.49.21 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 29 Oct 2009 14:49:22 -0700 (PDT) Message-ID: <4AEA0DCD.7070704@gmail.com> Date: Thu, 29 Oct 2009 15:49:01 -0600 From: Rob Sargent User-Agent: Thunderbird 2.0.0.23 (X11/20090817) 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=-1.11 tagged_above=-10 required=5 tests=BAYES_05=-1.11 X-Spam-Level: X-Archive-Number: 200910/141 X-Sequence-Number: 33340 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 Not thrilled with the "coded" length in the returned record but you could CASE that too and then you would only read the data once. If you need the explicit length range in the final result you could do select mod(length,100) * 100 as low_length, (mod(length,100) + 1) * 100 as high_length.... group by low_length, high_length, type You would of course get more type of records 400-500, 500-600 etc but again it all happens in a single read. And temp tables can be your friend too!