Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1s9gs2-004IBB-9V for pgsql-general@arkaria.postgresql.org; Wed, 22 May 2024 07:58:47 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1s9gs2-00ErQG-AK for pgsql-general@arkaria.postgresql.org; Wed, 22 May 2024 07:58:46 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1s9gs1-00ErQ8-MK for pgsql-general@lists.postgresql.org; Wed, 22 May 2024 07:58:45 +0000 Received: from mars.loonybin.net ([2600:3c03:e000:655::]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1s9grv-000AOZ-Mv for pgsql-general@lists.postgresql.org; Wed, 22 May 2024 07:58:44 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=loonybin.net; h= mime-version:user-agent:content-transfer-encoding:content-type :content-type:date:date:from:from:subject:subject:message-id; s= 3907404c; t=1716364713; bh=WdkafCJBMzbQRvwai49v5smvLqXdwU0QYconC cZcGEI=; b=axWojhCYGT54mcDct4/UR1HVzSoIRlZTLnIpHIEVuE0S3PPOz6z5i wDgxEBmjlOkDHe3vRHqbPL3j1Hzy5O9xkSo/3MpyUpvnuvws94vPhAYf/MSs93Qh 4whVbruI+8cFWbCgGEuKyi9YoqVVQgOFEtl02z0Cr1H5Ykpmnhwo3I40cCNEdAH+ jwJ2es8DRmCS2vKf1f7VadzcSg1zmUukXKRLw1V1IR5b+iV1xT34OsqeW/DTcWxg pkJpYCf8tKuJp6iCY1G/T3B2ASDQ3WZRL6h9gf87YMrxWCmacNSOmQBbTeXHEIpH wVR63CX/R4Ch4fb+2nPOfMFadtsiDhsww== Received: by mars.loonybin.net (Postfix) with ESMTPSA id 667E423900 for ; Wed, 22 May 2024 03:58:33 -0400 (EDT) Message-ID: <98fd5198e1fe4e162f1166fd0575844de8bb7714.camel@loonybin.net> Subject: Finding "most recent" using daterange From: Rob Foehl To: pgsql-general@lists.postgresql.org Date: Wed, 22 May 2024 03:58:32 -0400 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.52.1 (3.52.1-1.fc40) MIME-Version: 1.0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Coming back to PostgreSQL after a (decades-)long absence... =C2=A0If I have something like: CREATE TABLE example ( id integer NOT NULL, value text NOT NULL, dates daterange NOT NULL ); INSERT INTO example VALUES (1, 'a', '[2010-01-01,2020-01-01)'), (1, 'b', '[2010-01-01,)'), (1, 'c', '[,2021-01-01)'), (2, 'd', '[2010-01-01,2021-01-01)'), (2, 'e', '[2015-01-01,2020-01-01)'), (3, 'f', '[2014-01-01,2016-01-01)'), (3, 'g', '[2013-01-01,)'), (3, 'h', '[2012-01-01,)'), (3, 'i', '[2013-01-01,2017-01-01)'), (4, 'j', '[2010-01-01,2015-01-01)'); and I want to find the "most recent" value out of each group, meaning that having the greatest upper bound followed by the greatest lower bound, what I've managed to come up with thus far is: WITH intermediate AS ( SELECT e.id, e.value, e.dates FROM example AS e JOIN ( SELECT id, max(coalesce(upper(dates), 'infinity')) AS max_date FROM example GROUP BY id ) AS max_upper ON e.id =3D max_upper.id AND coalesce(upper(dates), 'infinity') =3D max_upper.max_date ) SELECT i.id, i.value, i.dates FROM intermediate AS i JOIN ( SELECT id, max(coalesce(lower(dates), '-infinity')) AS max_date FROM intermediate GROUP BY id ) AS max_lower ON i.id =3D max_lower.id AND coalesce(lower(dates), '-infinity') =3D max_lower.max_date; which produces the desired result for this minimal example: id | value | dates ----+-------+------------------------- 1 | b | [2010-01-01,) 2 | d | [2010-01-01,2021-01-01) 3 | g | [2013-01-01,) 4 | j | [2010-01-01,2015-01-01) I pretty quickly discovered that there's no max(daterange) -- although it isn't obvious what that would do, anyway -- and the "intermediate" CTE is what followed. Is there a better way? (Note that this doesn't try to handle duplicate ranges -- I haven't decided whether that'll be necessary in the real case. Assume it'll have something beyond daterange NOT NULL and/or some _agg() magic, eventually.) -Rob