Received: from localhost (unknown [200.46.208.211]) by mail.postgresql.org (Postfix) with ESMTP id CD3D1633356 for ; Fri, 3 Jul 2009 01:04:36 -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 32938-09 for ; Fri, 3 Jul 2009 01:04:34 -0300 (ADT) X-Greylist: delayed 00:15:41.702244 by SQLgrey-1.7.6 Received: from smtp.insa-lyon.fr (criges14.insa-lyon.fr [134.214.76.242]) by mail.postgresql.org (Postfix) with ESMTP id 87714633135 for ; Fri, 3 Jul 2009 01:04:34 -0300 (ADT) Received: from localhost (localhost [127.0.0.1]) by smtp.insa-lyon.fr (Postfix) with ESMTP id 96A8FF13A6; Fri, 3 Jul 2009 05:48:50 +0200 (CEST) X-Virus-Scanned: SMTP at INSA-LYON Received: from smtp.insa-lyon.fr ([127.0.0.1]) by localhost (criges14.insa-lyon.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3pmoA22Jjgqv; Fri, 3 Jul 2009 05:48:50 +0200 (CEST) Received: from [IPv6:::1] (liris.univ-lyon1.fr [134.214.142.10]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: nhandrianar) by smtp.insa-lyon.fr (Postfix) with ESMTPSA id C7B5AF1396; Fri, 3 Jul 2009 05:48:49 +0200 (CEST) Message-ID: <4A4D7F9B.2020107@free.fr> Date: Fri, 03 Jul 2009 05:48:43 +0200 From: nha Organization: Lyon, Rhone, France User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; fr; rv:1.9.1b3pre) Gecko/20090223 Thunderbird/3.0b2 MIME-Version: 1.0 To: Jasmin Dizdarevic CC: pgsql-sql@postgresql.org Subject: Re: Create custom aggregate function and custom sfunc References: <407d949e0907021421qb1df8b1o9468f343298f08dd@mail.gmail.com> In-Reply-To: <407d949e0907021421qb1df8b1o9468f343298f08dd@mail.gmail.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0 tagged_above=0 required=5 tests=none X-Spam-Level: X-Archive-Number: 200907/13 X-Sequence-Number: 32754 Hello, Le 2/07/09 23:21, Greg Stark a écrit : > On Thu, Jul 2, 2009 at 3:48 PM, Jasmin > Dizdarevic wrote: >> customer ; seg >> 111 ; L1 >> 111 ; L2 >> 111 ; L1 >> 222 ; L3 >> 222 ; L3 >> 222 ; L2 >> >> the result should look like this: >> >> 111: L1 - because L1 is higher than L2 and ratio of L1 : L2 is 2 : 1 >> 222: L3 - because L3 is higher than L2 and ratio of L3 : L2 is 2 : 1 > > Are you just looking for the most frequent seg for each customer? > > select distinct on (customer) customer,seg > from (select customer, seg, count(*) as n from tab group by seg) > order by customer, n desc > > That doesn't give the ratios though. > Some errors would occur with the above query from within the subquery because of a projection on customer column that is not a grouped column (neither an uniquely identified column by seg--seg is assumed not to be a primary key here according to the given examples of value). By the way, the ordered column n is not a member of the projected columns. Nevertheless, in the same direction as Greg Stark, the following query would approach the target result: SELECT T5A.customer, T5A.seg FROM ( SELECT T2.customer, T2.seg, COUNT(*) AS nb FROM cst T2 GROUP BY T2.customer, T2.seg ) T5A INNER JOIN ( SELECT T4.customer, MAX(T4.nb) AS maxNb FROM ( SELECT T2B.customer, T2B.seg, COUNT(*) AS nb FROM cst T2B GROUP BY T2B.customer, T2B.seg ) T4 GROUP BY T4.customer ) T5B ON T5A.customer = T5B.customer AND T5A.nb = T5B.maxNb where 'cst' is the reference table including 'customer' and 'seg' columns. This query considers a join between two tables: - the first table, aliased T5A, counts the multiplicity for each couple of 'customer' and 'seg'; - the secund table, aliased T5B, reveals the highest multiplicity for each 'customer' with regard to each 'seg' attached to customer. Then the join only retains the couples of 'customer' and 'seg' whom multiplicity equals the higher for the 'customer' of the current couple. Each multiplicity may be easily added to the resulting records by spanning the projected columns with T5A.nb column. A sort of ratio may also be added; one aggregated column may first be added to table T4 as SUM(T4.nb) -- that is, sum of multiplicity for each customer; then the resulting join may compute the ratio between the highest multiplicity and the sum of multiplicity for each customer, in addition to the seg (or list of seg) for which the multiplicity is the highest. Here is the modified query: SELECT T5A.customer, T5A.seg, T5A.nb/T5B.sumNb FROM ( SELECT T2.customer, T2.seg, COUNT(*) AS nb FROM cst T2 GROUP BY T2.customer, T2.seg ) T5A INNER JOIN ( SELECT T4.customer, MAX(T4.nb) AS maxNb, SUM(T4.nb) AS sumNb FROM ( SELECT T2B.customer, T2B.seg, COUNT(*) AS nb FROM cst T2B GROUP BY T2B.customer, T2B.seg ) T4 GROUP BY T4.customer ) T5B ON T5A.customer = T5B.customer AND T5A.nb = T5B.maxNb As is, this query may result to multiple couples of customer and seg with the same customer value when many seg relie as many times as many others for the current customer. This "edge effect" may be avoided in many ways depending on the original purpose. Regards. -- nha / Lyon / France.