Received: from localhost (unknown [200.46.208.211]) by mail.postgresql.org (Postfix) with ESMTP id 560B163225A for ; Fri, 24 Jul 2009 21:27:56 -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 82906-05 for ; Sat, 25 Jul 2009 00:27:36 +0000 (UTC) X-Greylist: from auto-whitelisted 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 3B575632274 for ; Fri, 24 Jul 2009 21:27:44 -0300 (ADT) Received: from localhost (localhost [127.0.0.1]) by smtp.insa-lyon.fr (Postfix) with ESMTP id 2F749F135B for ; Sat, 25 Jul 2009 02:27:42 +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 c0+CBSxwTvaI for ; Sat, 25 Jul 2009 02:27:41 +0200 (CEST) Received: from [127.0.0.1] (liris.univ-lyon1.fr [134.214.142.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: nhandrianar) by smtp.insa-lyon.fr (Postfix) with ESMTPSA id CF897F135A for ; Sat, 25 Jul 2009 02:27:40 +0200 (CEST) Message-ID: <4A6A513E.2090507@free.fr> Date: Sat, 25 Jul 2009 02:26:38 +0200 From: nha Organization: Lyon, Rhone, France User-Agent: Thunderbird 2.0.0.6 (Macintosh/20070728) MIME-Version: 1.0 To: PgSQL-sql Subject: Re: Need magical advice for counting NOTHING References: <4A67EEB2.1070302@gmx.net> In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0 tagged_above=-10 required=5 tests=none X-Spam-Level: X-Archive-Number: 200907/127 X-Sequence-Number: 32868 Hello, Le 23/07/09 10:23, Glenn Maynard a écrit : > On Thu, Jul 23, 2009 at 1:01 AM, Andreas wrote: >> SELECT user_name, log_type_fk, COUNT(log_type_fk) >> FROM log >> JOIN users ON (user_id = user_fk) >> WHERE (ts IS BETWEEN sometime AND another) >> GROUP BY user_name, log_type_fk >> ORDER BY user_name, log_type_fk > [...] > SELECT user_name, log_type.log_type, sum((log_type_fk IS NOT > NULL)::integer) AS count > FROM users JOIN log_type ON (true) LEFT JOIN log ON (user_id = user_fk > AND log.log_type_fk = log_type.log_type) > GROUP BY user_name, log_type.log_type > ORDER BY user_name, log_type.log_type; > [...] In the same direction as Andreas Krestchmer and Glenn Maynard (thanks to the latter for DDL assumed statements), the following query should also suit: SELECT user_name, log_type, COUNT(log_type_fk) FROM (users CROSS JOIN log_type) LEFT JOIN log ON (user_id = user_fk AND log_type_id = log_type_fk) WHERE (ts IS BETWEEN sometime AND another) GROUP BY user_name, log_type ORDER BY user_name, log_type It is syntactically nearer the original query and includes no class operator. Here are the two main ideas: - Building all the possible couples of user name and log type by cross-joining users and log_type tables; - Counting rows in log table matching each couple (user, log_type) from the previous cross-join (LEFT JOIN ensures that each row of the table on the left is mined). While it is formally assumed that user_id and log_type_id are respectively keys for users and log_type tables, it is semantically admitted here that user_name identifies user_id in users table and log_type identifies log_type_id in log_type table. Regards. -- nha / Lyon / France.