Создайте диапазон из времени начала и окончания, используя что-то вроде
tsrange (start_time, end_time, '[]') (for exclusive range boundaries)
tsrange (start_time, end_time, '()') (for inclusive range boundaries)
https://www.postgresql.org/docs/9.3/rangetypes.html
Используйте оператор перекрытия '&&' для проверки 2 диапазонов
https://www.postgresql.org/docs/9.3/functions-range.html
Оберните это в запрос, который может выглядеть следующим образом
SELECT p1.proc_id,
( SELECT COUNT(*)
FROM procedure p2
WHERE p1.anest_name = p2.anest_name
AND p1.proc_id <> p2.proc_id
AND tsrange (p1.start_time, p1.end_time, '()') && tsrange (p2.start_time, p2.end_time,'()')
) as count
FROM procedure p1
ORDER BY p1.proc_id
Какой тип границ диапазона вы используете, зависит от вашего понимания «одновременности». Это может означать перекрытие, содержащееся в другом таймфрейме или что-то еще. Возможно, вы захотите возиться с границами, но этот запрос должен соответствовать вашим оценочным результатам (или, по крайней мере, приблизиться к ним) ...