2017-03-21 2 views
0

내 스키마 (MySQL은, 이노 디비) :고유 한 하위 행을 기반으로 상위 행을 찾는 방법은 무엇입니까?

Conversation 
------------ 
id (int) 

User 
---- 
id (int) 

UserConversation 
---------------- 
user_id (int, FK) 
conversation_id (int, FK) 

그냥 대화에 사용자를 매핑 (다 대다).

이제 user1과 user2 사이에 새로운 대화를 만들기 전에이 두 사용자 간의 대화가 이미 DB에 있는지 확인하고 싶습니다. 사용자 1과

  • 회화, 사용자 2

아니라 : 사용자 1, 사용자 2와

  • 회화, 사용자 3 사용자 1
  • 대화를

    그래서 나는 선택합니다

  • User1, User3와의 대화

다른 단어 : 내 목표는 사용자 그룹 사이의 중복 대화를 만들 방지하는 것입니다. 이것을 달성하는 방법은 Yii2 ActiveRecord 또는 순수 SQL 쿼리입니까?

답변

2

where 절에 존재하는/존재하지 않는 일련의 조건을 사용하여 conversation이 특정 사용자 사이에 있는지 만 판단 할 수 있습니다.

select conversation_id, count(if(user_id in (1,2),1,null)) as in_user, count(*) as all_user 
from userconversations uc 
group by conversation_id 
having in_user=2 and all_user=2 

이 쿼리에 추가 조건을 필요하지 않습니다 :

select c.id 
from conversation c 
where exists (select 1 from userconversations uc where uc.conversation_id=c.id and uc.user_id=1) 
     and exists (select 1 from userconversations uc where uc.conversation_id=c.id and uc.user_id=2) 
     and not exists (select 1 from userconversations uc where uc.conversation_id=c.id and uc.user_id not in (1,2)) 

또 다른 방법은 기록의 수를 비교하는 것입니다 : 유일한 단점은 각 사용자에 대해 새 exists 기준을 추가 할 필요가 있다는 것입니다 where 절을 사용하면 목록에 두 명 이상의 사용자가 있지만 조건부 계산으로 인해 exists 버전보다 느릴 수 있습니다. 두 솔루션을 모두 테스트하고 어떤 솔루션이 더 적합한 지 확인해야합니다.

관련 문제