Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nVK9F-0001tH-Bv for pgsql-docs@arkaria.postgresql.org; Fri, 18 Mar 2022 21:28:37 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nVK9E-0003gq-00 for pgsql-docs@arkaria.postgresql.org; Fri, 18 Mar 2022 21:28:36 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nVK9D-0003gh-PQ for pgsql-docs@lists.postgresql.org; Fri, 18 Mar 2022 21:28:35 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nVK9A-0000dp-6K for pgsql-docs@postgresql.org; Fri, 18 Mar 2022 21:28:35 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 22ILSSx61228520; Fri, 18 Mar 2022 17:28:28 -0400 From: Tom Lane To: Erwin Brandstetter cc: pgsql-docs Subject: Re: count() counts ROW values that are NULL In-reply-to: References: Comments: In-reply-to Erwin Brandstetter message dated "Fri, 18 Mar 2022 21:58:15 +0100" MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-ID: <1228518.1647638908.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Date: Fri, 18 Mar 2022 17:28:28 -0400 Message-ID: <1228519.1647638908@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Erwin Brandstetter writes: > https://www.postgresql.org/docs/current/functions-aggregate.html#FUNCTIO= NS-AGGREGATE-TABLE > The manual says: >> count ( "any" ) =E2=86=92 bigint >> Computes the number of input rows in which the input value is not null. > But ROW values or composite types that "are null" are counted, anyway. Well, there's nulls and nulls. The SQL "IS NULL" construct is fairly badly designed IMO, because it considers both a plain NULL and a row-of-all-NULL-fields to be "null". count(), like just about everything in Postgres other than "IS NULL", considers only a plain NULL to be null. This is discussed somewhere in the manual, but I think it's under IS NULL, not under all the other places that'd have to be annotated if we decide to annotate as you're suggesting. (One example is that functions that are marked STRICT use the tighter interpretation.) You could use "COUNT(*) FILTER (WHERE NOT (whatever IS NULL))" if you want to count values meeting the IS NULL definition. (Buttressing my point that IS NULL is not well thought out, the obvious "whatever IS NOT NULL" doesn't work here, because it's not the inverse of "whatever IS NULL".) regards, tom lane