Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dIaPL-0001Jn-57 for pgsql-sql@arkaria.postgresql.org; Wed, 07 Jun 2017 12:49:55 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1dIaPK-0003MZ-O8 for pgsql-sql@arkaria.postgresql.org; Wed, 07 Jun 2017 12:49:54 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1dIaPJ-0003KQ-Uq for pgsql-sql@postgresql.org; Wed, 07 Jun 2017 12:49:54 +0000 Received: from out1-smtp.messagingengine.com ([66.111.4.25]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1dIaPB-0003Se-VB for pgsql-sql@postgresql.org; Wed, 07 Jun 2017 12:49:53 +0000 Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id 78A9A20A09; Wed, 7 Jun 2017 08:49:44 -0400 (EDT) Received: from frontend2 ([10.202.2.161]) by compute6.internal (MEProxy); Wed, 07 Jun 2017 08:49:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aklaver.com; h= content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-sender :x-me-sender:x-sasl-enc:x-sasl-enc; s=fm1; bh=Pmv/RIQvhRECbYMSvY zhHdROR4g2JoFszG7SLl9Jt1E=; b=HAWDa8Kq1Uh4zs3bp/aXzEZCh5t7OPLhIA +jt+xhfyfGeu4y9juVttLRMnoDjcl5lNKbnbdxgKWbXmlR7YJ90lSMcOnjShdt6m DjtiYuWgn71QXAYzws0TT8V53+wYAG8VZnjmq4wzCKfIZE6EgzByhTU84lS1tSa9 j0WmkY1B2F1PH+hIlBT14y7dTWM6PQFKooPfh8Q1QGQoJ/kqGv8QwN1+c1jDxbWY zBwShMGUrzWj9I7ctSSPGDfXeTofWiuagOmPSULbtSLHgtCdmk2E3WgVTCOnY8qp eCdVFGKbUm/QpQ5fZwvApEqOXn1bMx1Az9Nz+EP3yQNxJ+zq/GIA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-sender:x-me-sender:x-sasl-enc:x-sasl-enc; s= fm1; bh=Pmv/RIQvhRECbYMSvYzhHdROR4g2JoFszG7SLl9Jt1E=; b=haxZUXdg 7MdU1AMmvdumpkPUA+H33ekHHQqrFN0NDxJeGn3zA5PbRY6coMGg6pp1okOmhmoI FQwSs3/UZL2JAMtkTSbRDSEWAinBgxIZhj8OHnqeobu4faH5+V1FJmWtm1g8H76U wIm0mkY9uGYQ1xIKHHkKWuq4O5uM3FUjLkxEMQWQMNilI+w/yhnSew9M8v1Fyzal pf9temKFdCmHauhHxNAjSkrYGNxQR6QtNW+6Kw/+qyToxo0726/4hk0KedcXpeX5 LUBYkqbzso8RBA9+1dMNuhlBE9u6bxT9mE4H7m6j1RZt8+zK7M1XUvb8+8rifbj8 sl78+oHiLkVqqQ== X-ME-Sender: X-Sasl-enc: Nn2u6KOG0rZ7eU7AkjBGZDR/aKvnkxkOvFJznugpm591 1496839784 Received: from [192.168.1.2] (75-172-126-41.tukw.qwest.net [75.172.126.41]) by mail.messagingengine.com (Postfix) with ESMTPA id E61D82479C; Wed, 7 Jun 2017 08:49:43 -0400 (EDT) Subject: Re: Not getting the expected results for a simple where not in To: Jonathan Moules , pgsql-sql@postgresql.org References: <15c827e9305.ae02346553193.1322341002046903374@lightpear.com> From: Adrian Klaver Message-ID: Date: Wed, 7 Jun 2017 05:49:43 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.1.1 MIME-Version: 1.0 In-Reply-To: <15c827e9305.ae02346553193.1322341002046903374@lightpear.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Pg-Spam-Score: -2.7 (--) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-sql Precedence: bulk Sender: pgsql-sql-owner@postgresql.org On 06/07/2017 05:20 AM, Jonathan Moules wrote: > Hi List, > I'm a little confused by what seems like it should be a simple query and > was hoping someone could explain what's going on. > Using PG 9.4.x > > CREATE TABLE aaa.testing_nulls > ( > str character varying(10), > status character varying(2) > ) > > Data: > "first";"aa" > "second";"aa" > "third";null > "fourth";"bb" > null;"aa" > null;"bb" > > If I run: > select > str > from > aaa.testing_nulls > where > status in ('aa') > > Against the table, I get the expected result: > "first" > "second" > null > > But I want to get the items that don't have a value of 'aa'. Obviously > in this case I can simply add "not" to the "where status in" but that's > not suitable for my actual use-case (which is where this problem came to > light). Instead, I'm nesting the original as a subquery: > > select > * > from > aaa.testing_nulls > where > str not in > ( > select > str > from > aaa.testing_nulls > where > status in ('aa') > ) > > Conceptually to me at least, this should work. I expect to get the values: > "third" > "fourth" > But instead when I run it I get 0 results. > > It seems to relate to the nulls. If I change the above and add "and str > is not null" into the subquery: > > select > * > from > aaa.testing_nulls > where > str not in > ( > select > str > from > aaa.testing_nulls > where > status in ('aa') > and str is not null > ) > > It now gives the expected results. > Why is this? https://www.postgresql.org/docs/9.6/static/functions-subquery.html#FUNCTIONS-SUBQUERY-IN "Note that if the left-hand expression yields null, or if there are no equal right-hand values and at least one right-hand row yields null, the result of the NOT IN construct will be null, not true. This is in accordance with SQL's normal rules for Boolean combinations of null values." > (I tested this in SQLite too, and get the same behaviour, so I guess > it's a generic SQL thing I've never encountered before.) > Thanks, > Jonathan -- Adrian Klaver adrian.klaver@aklaver.com -- Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-sql