Имея следующую таблицу (conversations
):Выбор групп на основе совпадений в другой таблице
id | record_id | is_response | text |
---+------------+---------------+----------------------+
1 | 1 | false | in text 1 |
2 | 1 | true | response text 3 |
3 | 1 | false | in text 2 |
4 | 1 | true | response text 2 |
5 | 1 | true | response text 3 |
6 | 2 | false | in text 1 |
7 | 2 | true | response text 1 |
8 | 2 | false | in text 2 |
9 | 2 | true | response text 3 |
10 | 2 | true | response text 4 |
И другой справочной таблицы (responses
):
id | text |
---+----------------------+
1 | response text 1 |
2 | response text 2 |
3 | response text 4 |
Я ищу для запроса SQL для выход следующий:
record_id | context
----------+-----------------------+---------------------
1 | in text 1 response text 3 in text 2 response text 2
----------+-----------------------+---------------------
2 | in text 1 response text 1
----------+-----------------------+---------------------
2 | in text 2 response text 3 response text 4
Таким образом, каждый раз is_response
является true
и text
: в таблица ответов, совокупность контекст разговора до этой точки, игнорируя часть разговора, которая не заканчивается ответом в пуле.
В приведенном выше примере жизни текст ответа 3 в record_id
1.
Я пробовал следующий сложный SQL, но он ломает иногда агрегирование текст неправильно:
with context as(
with answers as (
SELECT record_id, is_response, id as ans_id
, max(id)
OVER (PARTITION BY record_id ORDER BY id
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS previous_ans_id
FROM (select * from conversations where text in (select text from responses)) ans
),
lines as (
select answers.record_id, con.id, COALESCE(previous_ans_id || ',' || ans_id, '0') as block, con.text as text from answers, conversations con where con.engagement_id = answers.record_id and ((previous_ans_id is null and con.id <= ans_id) OR (con.id > previous_ans_id and con.id <= ans_id)) order by engagement_id, id asc
)
select record_id, block,replace(trim(both ' ' from string_agg(text, E' ')) ,' ',' ') ctx from lines group by record_id, block order by record_id,block
)
select * from context
я уверен, Существует лучший способ.
Спасибо за ответ, к сожалению, в вашем решении агрегированного текст не сохраняет порядок строк, и я получаю текст и ответы смешаны –
@ShlomiSchwartz Я добавил «ODER BY» в совокупности, теперь все должно быть в порядке. – redneb
Работает как очарование. Не было знакомо с заказом внутри агрегатной функции. Спасибо. –