У меня есть такая таблица SQLite:

GroupID UserID
1       1
1       2
1       3
2       4
2       1

...и так далее. Затем, учитывая список UserID, я хотел бы получить groupID, в котором есть все эти идентификаторы пользователя и только эти идентификаторы пользователя.

Например, в этой таблице для списка (1,2,3) возвращаемое значение должно быть 1. Для списка (1,4) оно должно быть 2. Для списков (1,2) или (3, 4) ничего не возвращать.

Как лучше всего это сделать?

0
user3586515 29 Апр 2014 в 22:33

3 ответа

Лучший ответ
select GroupID 
from your_table 
where UserID in (1,2,3)
GROUP BY GroupID
HAVING COUNT(*) = 3
0
T McKeown 29 Апр 2014 в 18:37

Вам немного неясно в вопросе. Будет ли возвращено «1», если в списке будут 2 и 3?

Это пример подзапроса "набор внутри наборов". Самый общий и гибкий подход - использовать агрегирование с предложением having:

select GroupId
from table t
group by GroupId
having sum(case when UserId = 1 then 1 else 0 end) > 0 and
       sum(case when UserId = 2 then 1 else 0 end) > 0 and
       sum(case when UserId = 3 then 1 else 0 end) > 0 and
       sum(case when UserId not in (1, 2, 3) then 1 else 0 end) = 0;

В каждом предложении подсчитывается количество появлений каждого пользователя. > 0 требует, чтобы каждый пользователь появлялся хотя бы один раз.

Возможно, вам будет проще выразить это как:

select GroupId
from table t
group by GroupId
having count(distinct case when UserId in (1, 2, 3) then UserId) = 3 and
       count(distinct UserId) = count(*);

Однако вы должны быть уверены, что «3» соответствует количеству элементов в операторе in.

0
Gordon Linoff 29 Апр 2014 в 18:50

Вы также можете использовать зависимый подзапрос:

SELECT * 
FROM myTable t1
WHERE UserID IN (1, 2, 3) 
  AND NOT EXISTS 
      (SELECT 1 
       FROM myTable t2 
       WHERE t2.GroupId = t1.GroupId 
         AND UserId NOT IN (1, 2, 3));

Говоря простым языком, вы выбираете записи, содержащие указанные значения UserId, и отклоняете все, что не содержит в точности все три. Преимущество этого метода заключается в том, что в предложении IN допускается произвольное количество элементов, при этом не требуется точно знать, сколько вы передаете.

0
Paul Richter 29 Апр 2014 в 18:55