использование таблицы в состоянии SQL без включения содержимого этой таблицы в результаты - PullRequest
1 голос
/ 05 августа 2010

Скажем, у меня есть четыре таблицы: 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, которое не относится к конкретному файлу или файлам.

Ответы [ 2 ]

1 голос
/ 05 августа 2010

Казалось бы, это работает, не уверен, что это оптимально, но это единственный способ, которым я мог это выяснить:

select users.user_id, users.display_name
from users, contacts
where contacts.user_id = :user_id
and contacts.contact_id = users.user_id
and (
    select count(*)
    from userfiles
    where userfiles.user_id = users.user_id
    and userfiles.file_id in (:file_ids)
) < :number_of_files;

Выбирает все контакты, кроме тех, которые соответствуют всем file_ids. Он выбирает контакты, которые соответствуют некоторым из file_ids, так как он захватывает количество контактов, соответствующих указанным идентификаторам, а затем проверяет, меньше ли это количество предоставленных идентификаторов.

1 голос
/ 05 августа 2010

выберите 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 in (: 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

Кажется, что вы хотите, насколько я понимаю, то есть единственные пользователи, у которых нет всехидентификаторы файлов.Если я что-то неправильно понял, пожалуйста, дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...