Re: Functions in sort order - undocumented restriction

From: "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>
To: andrew(at)grillet(dot)co(dot)uk, pgsql-docs(at)lists(dot)postgresql(dot)org
Subject: Re: Functions in sort order - undocumented restriction
Date: 2018-02-10 20:54:46
Message-ID: CAKFQuwb_7UWTYgAGAmJn-PE2qFLc5VZgjAr7ZNSWYNJcmWg8rw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-docs

On Sat, Feb 10, 2018 at 4:40 AM, PG Doc comments form <
noreply(at)postgresql(dot)org> wrote:

> The following documentation comment has been logged on the website:
>
> Page: https://www.postgresql.org/docs/9.5/static/queries-order.html
> Description:
>
> This works:
>
> select distinct o.bid, organisation, posttown, replace(case when phone =''
> then null else trim(phone) end, ' ', ''), phone, o.active, website, email,
> (select count(*) from notes as n where n.bid = o.bid) as nn from
> organisations as o right join notes as n on o.bid = n.bid where true order
> by replace(case when phone ='' then null else trim(phone) end, ' ', '')
> nulls last ;
>
> This does not work:
>
> select distinct (o.bid), organisation, posttown, replace(case when
> postcode
> ='' then null else trim(postcode) end, ' ', '') as pc, phone, o.active,
> website, email, (select count(*) from notes as n where n.bid = o.bid) as nn
> from organisations as o right join notes as n on o.bid = n.bid where true
> order by replace(case when phone ='' then null else trim(phone) end, ' ',
> '') nulls last ;
> ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select
> list
> LINE 1: ...n notes as n on o.bid = n.bid where true order by replace(ca...
>
> The documentation does not explain the restriction, nor that, or why, you
> cannot use 'as' to rename the field and then cite the renamed version.
>

​Let me get some clarity now since my first reply saw an "ON" clause where
there isn't one...

What was the point of adding parens around o.bid in the second query? (I
assumed it was to do DISTINCT ON but you didn't add the word ON)

Why did you change replace(case when phone...) in the first query with
replace (case when postcode...) in the second query - but only in the
select-list? (phone no longer exists in the select-list and thus you get
the error.)

The following works just fine with an alias in the ORDER BY:

WITH vals (v,t,o) AS ( VALUES
(1,'a',10),(2,'c',20),(3,'d',30),(3,'b',40),(4,'e',50) )
SELECT DISTINCT v, replace(t || '2', ' ', '') AS v2
FROM vals ORDER BY v2

Adding "o" to the ORDER BY provokes the error you have been seeing.

Tom has explained why this is the case. In short, DISTINCT seems to
effectively remove the ability to specify "arbitrary expressions from input
column values" in the ORDER BY - though you can still specify non-arbitrary
expressions, as long as they are the same expressions that are used in the
select-list.

David J.

In response to

Browse pgsql-docs by date

  From Date Subject
Next Message PG Doc comments form 2018-02-12 05:02:29 .
Previous Message Tom Lane 2018-02-10 19:06:00 Re: Documentation of EXCEPT ALL may have a bug