SQL-запрос для определения полностью содержащего подмножества
Я ломаю голову, чтобы найти решение следующего вопроса:
У меня есть таблица с двумя полями, USER_ID и CLIENT_ID. Для каждого USER_ID есть от 1 до n CLIENT_ID.
Допустим, пользователь А связан с клиентами 1,2 и 3. Я хочу создать запрос, который возвращает других пользователей, которые также связаны со всеми этими клиентами. Они могут быть связаны с большим количеством клиентов, но они должны иметь ссылки на все клиенты пользователя A.
Пример: пользователь B имеет ссылки на клиентов 1,2,3,4. Пользователь C имеет ссылки на клиентов 1,2. Затем запрос должен вернуть пользователя B, поскольку пользователь B имеет ссылки на все клиенты пользователя A. Пользователь C не должен быть возвращен, так как он имеет ссылки только на некоторых, но не на всех клиентов пользователя A.
Это кажется обманчиво простой проблемой, но я не могу на всю жизнь придумать запрос, который удовлетворяет моим ограничениям. Есть ли опытные гуру SQL, которые могут мне помочь?
2 ответа
Делая ряд предположений имени и типа данных...
DECLARE
@UserId int
,@ClientCount int
DECLARE @Clients as table
(ClientId int not null)
-- All clients for the "target" user
INSERT @Clients
select Clientid
from MyTable
where UserId = @userId
-- Track how many there are
SET @ClientCount = @@rowcount
-- List all users that have those clients
SELECT mt.UserId, count(*) HowMany
from Mytable mt
inner join @Clients cl
on cl.ClientId = mt.Clientid
where UserId <> @UserId
group by mt.UserId
having count(*) = @ClientCount
У меня нет таблицы, чтобы проверить это, но она должна работать с небольшой отладкой.
SELECT uc.user_id, u.username, COUNT(*) as client_count
FROM user u
INNER JOIN user_client uc
USING (user_id)
WHERE uc.client_id IN (
SELECT client_id
FROM user_client
WHERE user_id = {ID of user A}
)
GROUP BY uc.user_id, u.username
HAVING client_count = (
SELECT COUNT(*)
FROM user_client
WHERE user_id = {ID of user A}
)
Непроверенный и, возможно, специфичный для MySQL, но что-то подобное должно работать.