我将通过示例解释问题,因此在给定以下数据结构的情况下很容易理解:
id userId
1 1
1 2
2 2
3 2
1 3
2 3
我可以为一组用户获取id
的列表,如下所示:
declare @tmp table (id int, userId int)
insert into @tmp values(1,1), (1,2), (2,2), (3,2), (1,3), (2,3)
select id from @tmp
where userId in (1,2,3)
group by id
这将按预期返回以下内容:
id
1
2
3
我的问题是,我怎样才能获得在where
子句中为 EVERY userId映射的ID?例如userId in (1,2,3)
的结果应为1
,userId in (2,3)
的结果应为1,2
我已尝试浏览每个ID然后合并这些但到目前为止没有找到实际解决方案的运气。
注意解决方案必须适用于更大的数据集,想象数百万行和数千个userIds,解决方案的效率并不重要(因为它不必经常运行)
第二次注意我刚刚注意到计算结果实际上并不能保证正确性,因为两个不同的userId可能具有相同的映射计数但映射到不同的项目。在那种情况下,它不再是一个交叉点
答案 0 :(得分:1)
我使用临时表来存储用户ID
declare @tmp table (id int, userId int)
insert into @tmp values(1,1), (1,2), (2,2), (3,2), (1,3), (2,3)
declare @userid table (id int)
insert into @userid values (1), (2), (3)
select
t.id
from
(select *, cnt = count(*) over () from @userid) u
join @tmp t on u.id = t.userId
group by t.id, u.cnt
having u.cnt = count(distinct u.id)
答案 1 :(得分:1)
如果您唯一的问题是您只想指定一次用户ID,请使用您的用户表:
with u as (select userid from users where userid in (1,2,3))
select id
from mytable
where userid in (select userid from u)
group by id
having count(distinct userid) = (select count(*) from u);
如果您想对无效的用户ID做出反应,结果为空,那么您可以使用values子句替换users表:
with u as (select userid from (values (1), (2), (3)) AS ids(userid))
答案 2 :(得分:1)
您可以避免count distinct
以及不止一次输入userId
值 - 或者如果您从动态查询中填充@i
数据集的等效值,则可以避免:
declare @t table (id int, userId int);
insert into @t values(1,1), (1,2), (2,2), (3,2), (1,3), (2,3);
declare @i table (i int);
insert into @i values(1),(2),(3);
select t.id
from @i as i
join @t as t
on i.i = t.userId
group by t.id
having count(i.i) = (select count(1) from @i);
答案 3 :(得分:0)
一种方法是使用HAVING
:
SELECT id
FROM YourTable
GROUP BY id
HAVING COUNT(CASE WHEN UserID = 1 THEN 1 END) > 0
AND COUNT(CASE WHEN UserID = 2 THEN 1 END) > 0
AND COUNT(CASE WHEN UserID = 3 THEN 1 END) > 0;