假设我有四个表,users
,contacts
,files
和userfiles
。
用户可以上传文件并拥有联系人。他们可以选择与联系人共享上传的文件。
当用户选择一个或多个上传的文件时,我想显示他们尚未与之共享所有选定文件的联系人列表。因此,如果他们选择了一个文件,则会显示尚未看到该文件的联系人。如果选择了多个文件,则会显示尚未查看所有文件的联系人。
现在,我正在尝试这样的查询(使用sqlite3):
select users.user_id, users.display_name
from users, contacts, userfiles
where contacts.user_id = :user_id
and contacts.contact_id = users.user_id
and (
userfiles.user_id != users.user_id
and userfiles.file_id != :file_id
);
请注意,如果选择了多个文件,则最后一行会在循环中自动生成。
其中
:user_id
是试图共享文件的用户,而:file_id
是该文件,如果用户已经可以看到该文件,则将其从结果中省略。我最后得到的是一个列表,该列表共享除选定文件之外的任何文件,因此,如果用户与任何一个联系人共享多个文件,则该联系人会多次出现在列表中。如何避免重复?我只想检查文件是否已被共享,而不要获取不涉及一个或多个特定文件的所有
userfiles
内容。
最佳答案
选择users.user_id,users.display_name
来自用户,联系人为c
其中c.user_id =:user_id
和c.contact_id = users.user_id
并且不存在(
选择user_id
从用户文件作为uf
其中uf.user_id = c.contact_id
和uf.file_id在(:file_ids)中
);
请注意,:file_ids
是您的所有file_id,用逗号分隔。不再循环运行多个查询!
编辑:
这是我正在测试的数据:
create table users (user_id integer primary key, display_name text);
insert into users values (1,"bob");
insert into users values (2,"jim");
insert into users values (3,"bill");
insert into users values (4,"martin");
insert into users values (5,"carson");
create table contacts values (user_id integer, contact_id integer);
insert into contacts select u1.user_id, u2.user_id from users u1, users u2 where ui.user_id!=u2.user_id;
create table userfiles (user_id integer, file_id integer);
insert into userfiles values (1,10);
insert into userfiles values (2,10);
insert into userfiles values (3,10);
insert into userfiles values (4,10);
insert into userfiles values (1,20);
insert into userfiles values (2,30);
然后,如果我用
:user_id
= 5和:files_id
= 20,30运行查询,则会得到:select users.user_id, users.display_name
from users, contacts as c
where c.user_id = 5
and c.contact_id = users.user_id
and not exists (
select user_id
from userfiles as uf
where uf.user_id = c.contact_id
and uf.file_id in (20,30)
);
UserID|Display_Name
3 |bill
4 |martin
据我了解,这似乎是您想要的,即,唯一没有全部文件ID的用户。如果我误解了一点,请告诉我。
关于join - 在sql条件下使用表而不将表的内容合并到结果中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3410968/