2016-09-06 3 views
0

나는 apps 테이블을 가지고 있습니다. 각 앱에는 conversationsusers이 많이 있습니다. 대화에 많은 messages이 있고 각 메시지는 visitor 또는 user에 속할 수 있으며 visitor은 많은 대화를 가질 수 있습니다.쿼리 결과가 중복됩니다.

각 대화마다 가장 최근에 대화에 쓴 사용자의 이름과 아바타를 첨부하고 싶습니다.

사용자가 답을 얻지 못한 경우 가장 최근에 만든 사용자의 avatars을 앱 이름과 함께 가져 와서 대신 사용하고 싶습니다.

는 어떤 도움을 크게이다

select 
     c.id, 
     c.last_message, 
     c.last_activity, 
     coalesce(last.display_name, a.name || ' Team') as name, 
     array_agg(last.avatar) 
     from messages m 
     left join conversations c on c.id = m.conversation_id 
     left join apps a on a.id = c.app_id 
     left join lateral (
      select u.id, u.display_name, u.avatar 
      from users u 
      where u.id = m.user_id 
    ) as last on true 
     where c.visitor_id = 'c6p77hu9v000a4zcth4lnefn9' 
     group by c.id, last.display_name, last.avatar, a.name 
     order by c.inserted_at desc 

을 지금까지 가지고 있지만,이 같은 대화 ID에 대해 여러 결과를 반환, 내가 응용 프로그램 사용자를 얻기에 해결책을 발견하지 않았습니다 아바타 것입니다 apprecicated

+0

이것이 해결되는지 확실하지 않습니다. 최근에 회신한다는 것은 특정 대화에 마지막으로 삽입 된 행을 가져 오려는 것을 의미합니다. 그 대화에 MIN/MAX()를 사용해 보셨습니까? 테이블 구조와 샘플 출력을 보여주는 것이 더 좋을 것입니다. –

+0

원하는 출력 내에서 샘플 데이터를 제공하면 도와 드릴 수 있습니다 :) – kbball

답변

1

각 대화마다 가장 최근에 대화에 쓴 사용자의 이름과 아바타를 첨부하고 싶습니다.

그렇게하려면 측면 하위 쿼리를 사용할 수 있지만, 당신은 또한 다음 마지막 메시지가 처음되도록 방법으로 ORDER BY를 추가 할 해당 마지막 행을 얻을 LIMIT 1를 사용해야합니다. 내가 생각한다면, 당신은 메시지가 전송 된 날짜와 시간을 저장 message 테이블의 열 message_datetime을 가지고, 당신은 사용할 수 있습니다 : 한 사용자가 응답하지 않은 경우

select 
     c.id, 
     c.last_message, 
     c.last_activity, 
     coalesce(last.display_name, a.name || ' Team') as name, 
     last.avatar 
from 
    conversations c 
    left join apps a on a.id = c.app_id 
    left join lateral (
     select 
      u.id, u.display_name, u.avatar 
     from 
      users u 
      inner join messages m on u.id = m.user_id 
     where 
      c.id = m.conversation_id 
     order by 
      m.message_datetime desc 
     limit 1 
    ) as last on true 
where 
    c.visitor_id = 'c6p77hu9v000a4zcth4lnefn9' 
order by 
    c.inserted_at desc 

, 다음 대신 내가 좋겠 가장 최근에 만든 3 명의 사용자의 아바타를 앱 이름과 함께 가져 와서 대신 사용합니다.

이 쿼리는 이전과 상관 관계가 없으므로 간단합니다. 가정 당신의 users 날짜와 사용자가 생성 된 시간과 created_datetime 열, 당신은 간단한 쿼리 사용할 수 있습니다 :

select 
    u.id, u.display_name, u.avatar 
from 
    users u 
order by 
    u.created_datetime desc 
limit 3 

을 그리고 당신은 제어 할 수 COALESCE을 사용하여, 이전 쿼리에서 하위 쿼리로 사용할 수 있습니다 사용할 정보 :

select 
     c.id, 
     c.last_message, 
     c.last_activity, 
     coalesce(last.display_name, a.name || ' Team') as name, 
     coalesce(array[last.avatar], last_all.avatar) as avatar 
from 
    conversations c 
    left join apps a on a.id = c.app_id 
    left join lateral (
     select 
      u.id, u.display_name, u.avatar 
     from 
      users u 
      inner join messages m on u.id = m.user_id 
     where 
      c.id = m.conversation_id 
     order by 
      m.message_datetime desc 
     limit 1 
    ) as last on true 
    left join (
     select 
      array_agg(u.avatar) as avatar 
     from 
      users u 
     order by 
      u.created_datetime desc 
     limit 3 
    ) last_all on true 
where 
    c.visitor_id = 'c6p77hu9v000a4zcth4lnefn9' 
order by 
    c.inserted_at desc 
+0

이것은 완벽합니다. 정말 고마워요. – Tarlen

관련 문제