Буду писать вырезками из своего кода на Delphi с комментариями.
Суть следующего кода в том, чтоб получить протокол звонков за последние несколько (FLastDays) дней от текущей даты.
Для этой цели сначала на основе даты начала периода определяю cl_calls.id
Затем отдельно читаю таблицу cl_calls и отдельно читаю cl_segments с объединением в нее cl_participants и cl_party_info.
Последний запрос был взят по мотивам из самой базы PostgreeSQL, там есть встроенная функция database_single.cl_get_call_log
По идее она должна как раз и собирать лог звонков (судя из названия), внутри нее есть комментарии и выборка звонков на основе их типа и ряда условий, бегло пробежавшись видно что информация там очень полезная и выборка делается как-то с учетом специфики внутреннего хранения информации (анализируются типы звонков и ряд дополнительных значений). Возможно внутри нее и кроется ответ на Ваш вопрос. Но я не стал с ней разбираться, я был ограничен по времени. А вообще там есть много полезных готовых функций, даже по их названиям легко понять их назначения, но нужно разобраться как их правильно применять.
// получаем минимальное ID (текущая дата минус заданное число дней) от которого потом делаем чтение таблиц
mincallid:=0;
st:='SELECT min(id) FROM cl_calls WHERE start_time>='+#39+formatdatetime2('yyyy.mm.dd hh:nn:ss',int(now-FLastDays))+#39;
FDQuery1.Open(st);
if not FDQuery1.Eof then
begin
mincallid:=VariantToId(FDQuery1.Fields[0].Value);
end;
// получаем звонки
FDQuery1.SQL.Clear;
FDQuery1.Open('SELECT * FROM cl_calls WHERE id>='+IntToStr(mincallid));
// получаем сегменты звонков с доп информацией
FDQuery1.SQL.Clear;
FDQuery1.Open('SELECT cl_segments.*, '+
'src_p.id AS srcp_id, src_p.info_id AS srcp_info_id, src_p.start_time AS srcp_start_time, src_p.answer_time AS srcp_answer_time, src_p.end_time AS srcp_end_time, src_p.recording_url AS srcp_recording_url, '+
'dst_p.id AS dstp_id, dst_p.info_id AS dstp_info_id, dst_p.start_time AS dstp_start_time, dst_p.answer_time AS dstp_answer_time, dst_p.end_time AS dstp_end_time, dst_p.recording_url AS dstp_recording_url, '+
'src_info.id AS srci_id, src_info.dn_type AS srci_dn_type, src_info.dn AS srci_dn, src_info.caller_number AS srci_caller_number, src_info.display_name AS srci_display_name, src_info.dn_class AS srci_dn_class, '+
'dst_info.id AS dsti_id, dst_info.dn_type AS dsti_dn_type, dst_info.dn AS dsti_dn, dst_info.caller_number AS dsti_caller_number, dst_info.display_name AS dsti_display_name, dst_info.dn_class AS dsti_dn_class '+
'FROM cl_segments '+
'join cl_participants src_p on src_p.id = cl_segments.src_part_id '+
'join cl_participants dst_p on dst_p.id = cl_segments.dst_part_id '+
'join cl_party_info src_info on src_info.id = src_p.info_id '+
'join cl_party_info dst_info on dst_info.id = dst_p.info_id '+
'WHERE cl_segments.call_id>='+IntToStr(mincallid)+' ORDER BY cl_segments.id');