Re: Return rows in input array's order? - Mailing list pgsql-general

From Andrew Gierth
Subject Re: Return rows in input array's order?
Date
Msg-id 87o7msabdp.fsf@news-spur.riddles.org.uk
Whole thread Raw
In response to Return rows in input array's order?  (Dominique Devienne <ddevienne@gmail.com>)
Responses Re: Return rows in input array's order?
List pgsql-general
>>>>> "Dominique" == Dominique Devienne <ddevienne@gmail.com> writes:

 Dominique> Hi. With an integer identity primary key table,
 Dominique> we fetch a number of rows with WHERE id = ANY($1),
 Dominique> with $1 an int[] array. The API using that query must return
 Dominique> rows in the input int[] array order, and uses a client-side
 Dominique> mapping to achieve that currently.

 Dominique> Is it possible to maintain $1's order directly in SQL?
 Dominique> Efficiently?

This is the correct way:

SELECT ... FROM unnest($1) WITH ORDINALITY AS u(id,ord)
           JOIN yourtable t ON t.id=u.id
 ORDER BY u.ord;

This doesn't assume there won't be holes (if you want, you can change it
to a left join to get a null row instead for missing ids).

The query plan you get for this should be something like:

  Nested Loop
    Function Scan on unnest
    Index Scan on yourtable_pkey

(less likely, depending on table sizes, would be a Merge Join with
similar inputs. If your table is very small you might get a hashjoin and
separate sort, but that shouldn't happen with realistic data sizes.)

Notice that this is entirely deterministic about the output ordering
without needing to do any sorting. (The planner knows that the output of
WITH ORDINALITY function scans is automatically ordered by the ordinal
column, so it will usually generate plans that take advantage of that.)
The presence of "ORDER BY u.ord" ensures that the output order is
correct regardless of plan choice.

-- 
Andrew (irc:RhodiumToad)



pgsql-general by date:

Previous
From: Peter Eisentraut
Date:
Subject: Re: ICU, locale and collation question
Next
From: Dominique Devienne
Date:
Subject: Re: Return rows in input array's order?