我偶然发现了一个我在过去一周试图解决的问题,希望社区能够帮助我解决这个问题。我会尽力解释。
User Table Channel Table Member Table
id | name id ch.Id | u.Id
----|---- ----- -------------
1 | george 1 1 | 1
2 | john 2 1 | 2
3 | joe 3 2 | 1
4 | jessie 4 2 | 3
3 | 1
3 | 3
所以如图所示,我有3张桌子。成员表处理用户表与渠道表之间的关联。我正在尝试做的是仅拉出与一个渠道相关联的用户,而不在查询中识别该渠道。
到目前为止,我至少有一个呈现两个给定用户的概念,但是如下所示的查询将呈现两个用户所包含的每个频道。再次,我想将其进一步并且仅与请求的用户一起拉出一个频道,而不会(如果可能)在查询中提及频道ID
SELECT ch.id as chid, u.id as uid FROM channels AS ch
LEFT JOIN members as mem on ch.id = "mem"."channelId"
LEFT JOIN users AS u ON u.id = "mem"."userId" WHERE u.id in (1,2);
希望我对此做了清楚的解释。谢谢大家!
答案 0 :(得分:0)
您可以使用not exists
:
select m.*
from members m
where not exists (select 1
from members m2
where m2.u_id = m.u_id and m2.ch_id <> m.ch_id
);
答案 1 :(得分:0)
如果我正确理解了您的意图,则下面的SQL代码将为您提供帮助。
SELECT
U.*,
M.*
FROM USER U
INNER JOIN MEMBER M ON (M.U.ID = U.ID)
WHERE U.ID IN (1,2,3,4)
AND M.CH.ID IN (1,2,3,4);
它选择数据而不访问通道表。 但是,结果将带有重复的行,在这种情况下,您可以对所需的字段进行GROUP BY,并且如果需要,可以使用一些与组一起使用的函数来进一步处理数据(组concat函数)。
此外,正如已经指出的,您可以使用EXISTS或NOT EXISTS和子查询。根据应用程序应达到的容量,它可能会成为性能问题。
干杯
答案 2 :(得分:0)
您可以使用GROUP BY
子句来标识只有一个频道的用户:
select u_id
from members m
group by u_id
having min(ch_id) <> max(ch_id);
答案 3 :(得分:0)
只有1个频道ID的用户ID?
select max(mem.channelId) as cid, mem.userId as uid
from members as mem
group by mem.userId
having count(distinct mem.channelId) = 1;
如果您担心成员表包含在其他表中已删除的ID?
(如果使用外键来强制参照完整性,则不应该如此)
然后将其他表内部连接到它。
select max(mem.channelId) as cid, mem.userId as uid
from members as mem
join channels as ch on ch.id = mem.channelId
join users as u on u.id = mem.userId
group by mem.userId
having count(distinct mem.channelId) = 1;
示例代码段:
declare @users table (id int identity(1,1) primary key, name varchar(30));
declare @channels table (id int identity(1,1) primary key, name varchar(30));
declare @members table (ChannelId int, UserId int);
insert into @users (name) values ('george'),('john'),('joe'),('jessie');
insert into @channels (name) values ('one'),('two'),('three'),('four');
insert into @members (channelId, userId) values (1,1),(1,2),(2,1),(2,3),(3,1),(3,3);
select
mem.userId as uid, max(mem.channelId) as cid
, max(u.name) as uname
, max(ch.name) as cname
from @members as mem
join @channels as ch on ch.id = mem.channelId
join @users as u on u.id = mem.userId
group by mem.userId
having count(distinct mem.channelId) = 1;