Skip to main content

Join placement

joinPlacement says where a join stands once a query comes apart: clause, as a clause of the query beside FROM and WHERE, or from_list, inside the FROM it belongs to, one line per join in the column the FROM's table starts in.

Default: clause.

from_list reads a join as part of the relation it extends rather than as a step of the query. With clauseAlignment right it is the layout of The Art of PostgreSQL, where 157 of the book's 166 joins sit in their FROM. A join there never widens the river, however long its keywords are.

With left-aligned clauses​

select a from results join races using (raceid) left join status using (statusid) where x = 1
select a
from results
join races using (raceid)
left join status using (statusid)
where x = 1
select a from results join races using (raceid) left join status using (statusid) where x = 1
select a
from results
    join races using (raceid)
    left join status using (statusid)
where x = 1

With clauseAlignment: right​

select a from results join races using (raceid) left join status using (statusid) where x = 1
   select a
     from results
     join races using (raceid)
left join status using (statusid)
    where x = 1
select a from results join races using (raceid) left join status using (statusid) where x = 1
select a
  from results
       join races using (raceid)
       left join status using (statusid)
 where x = 1

As a clause, left join is the widest keyword and moves the edge for the whole query. In the FROM it starts in the body column and moves nothing.

A FROM with several items​

select artist.name, album, duration from four_albums join artist using (artist_id), lateral get_all_albums(artist_id) order by artist_id
  select artist.name, album, duration
    from four_albums join artist using (artist_id),
         lateral get_all_albums(artist_id)
order by artist_id
select artist.name, album, duration from four_albums join artist using (artist_id), lateral get_all_albums(artist_id) order by artist_id
  select artist.name, album, duration
    from four_albums
         join artist using (artist_id),
         lateral get_all_albums(artist_id)
order by artist_id

A join belongs to the item before it, so it follows that item and the comma ends the item after its join. As a clause, a join cannot be lifted out of a FROM that lists more than one item, which is why under clause it stays on the FROM's line.

The joins come apart when the query does. A statement of one clause never does, so a clause that trails it stays beside it: set intervalstyle to postgres is one line under either value.