У меня сформировалась такая модель оформления запросов sql.
1. Один уровень запроса я насаживаю на ось. Слева от оси - клаузы синтаксиса sql: select, update, insert, delete, from, set, join-ы всех разновидностей, where, order by, group by и так далее. Справа от оси - атрибуты запроса, скобки следующего уровня запроса.
2. В выражениях оконных функций делаю ось относительно partition by/order by.
3. Булевые выражения после on или where выравниваю так:
- операторы первого приоритета (and) идут в левую часть оси;
- сравнения и следующий уровень более низкого приоритета (or) - в правую часть оси.
4. наименования join сокращаем максимально кратко:
- вместо inner outer join просто join,
- вместо left outer join - left join и так далее.
5. В части join...on присоединяемые поля таблицы ставлю в левую часть равенства в булевых выражениях:
join t1 on t1.a_id = t2.id
and t1.begin_date < t2.end_date
но не так:
join t1 on t2.id = t1.a_id
and t2.end_date > t1.begin_date
6. Наименования атрибутов, которые относятся к одной таблице в текущем уровне или прошлом, или имеющие по смыслу более связанное значение, можно писать в одну строчку:
select a.id, a.name,
b.position
...
7. Запятые в перечислениях атрибутов удобно иметь в начале строки, когда запрос изменяют каждый день или находится в стадии активной разработки. Но постоянно просматривать такой запрос в режиме изучения, на мой взгляд - неудобно. Поэтому, когда активная фаза исправлений заканчивается, запятые перемещаю в конец строки.
select a.id
, a.name
, b.position
после:
select a.id, a.name,
b.position
Итог. Эта модель не идеальна. Нужно делать отступы для select и from на первом уровне, чтобы посадить на ось where, group by, order by; также join-ы следующего уровня напирают на ось предыдущего.
PS: Ваш запрос я бы оформил так: