2012-03-09 4 views
2

Я пишу приложение C# и использую Access .mdb. У меня есть таблица с сообщениями электронной почты и таблица с сообщениями (каждый почтовый ящик может быть назначен нескольким группам работников).SQL: выберите данные, которые не имеют отношений в другой таблице

Я хочу получать сообщения из первой таблицы, которые НЕ назначены какой-либо команде, то есть либо не имеют записей во второй таблице, либо имеют пустую запись. Он работает нормально с пустыми вводами, но не возвращает строки, которые вообще не имеют этой записи назначения.

Я использую следующий запрос:

SELECT TOP 10 Mails.* 
FROM Mails INNER JOIN MailAssignments ON Mails.msgId = MailAssignments.msgId 
    WHERE (Mails.msgId <= ?) 
    AND 
    (Mails.msgId NOT IN (SELECT msgId FROM MailAssignments)) 
    OR (MailAssignments.forTeam IS NULL) 
    OR (MailAssignments.forTeam = '') 

UPDATE:

мне нужно использовать какой-то JOIN, потому что в некоторых условиях запрос должен также возвращать строки, имеющие отношение в другая таблица (например, когда кто-то хочет отображать сообщения из своей команды и неназначенные сообщения).

UPDATE:

Хорошо, я предполагаю, что я могу сделать это проще, удалив любое задание из второй таблицы, так что мне не нужно, чтобы проверить пустые задания, только те, которые не существуют вообще. Но мне по-прежнему нужно иногда показывать данные, которые назначаются ALONG WITH с данными, которые не были назначены. И мне нужно, чтобы построить один запрос за то, что будет иметь только разные параметры изменились:/

UPDATE/РЕШЕНИЕ:

Я сделал еще некоторые коррективы, но LEFT JOIN в основном сделал трюк для меня! Спасибо за этот намек и всю вашу помощь, ребята!

+0

Обновление: Вы не можете иметь сообщения от своей команды для почты которые не назначены команде, не так ли? –

+0

Я хочу, чтобы работники видели сообщения своей команды по умолчанию, но когда они разрешают другие виды, они должны видеть также неназначенные сообщения (поэтому они могут затем назначить их своей команде, например) – Val

+0

Я сделал несколько настроек, но LEFT JOIN в основном сделал трюк для меня! Спасибо за помощь ребята! – Val

ответ

4

Это должно быть достаточно:

SELECT TOP 10 Mails.* 
FROM Mails 
    WHERE (Mails.msgId <= ?) 
    AND 
    (Mails.msgId NOT IN (SELECT msgId FROM MailAssignments)) 

Читает описание, кажется, тх вы можете иметь строки в MailAssignments, которые связаны с Mails, но команда на самом деле не быть назначена (forTeam столбца имеет . пустая строка Это не хороший дизайн, но в этом случае, используйте:

SELECT TOP 10 Mails.* 
FROM Mails 
    LEFT JOIN 
    MailAssignments ON Mails.msgId = MailAssignments.msgId 
WHERE (Mails.msgId <= ?) 
    AND ( (MailAssignments.forTeam IS NULL) 
     OR (MailAssignments.forTeam = '') 
    ) 
+0

С оговоркой, что вы можете получить более 10 записей, так как Access возвращает совпадения. Вы можете обойти это, указав уникальный столбец (поле) в инструкции Order By. – Fionnuala

+0

Всё нормально для меня. Самое главное, что другие условия работают правильно (включая ключевое слово JOIN) – Val

1

Так как вы использовали присоединиться, я думаю, вам нужны столбцы из таблицы 2, используйте OUTER JOIN вместо INNER JOIN (он возвращает записи в таблице без совпадения в соединении).

Если они вам не нужны, я согласен с @ypercube.

2

Присоединяйтесь Mails к подмножеству MailAssignments пытается сопоставить письма с существующими заданиями (где forTeam <> '') и выбрать те, где совпадения не произошло:

SELECT TOP 10 
    Mails.* 
FROM Mails 
    LEFT JOIN MailAssignments ON Mails.msgId = MailAssignments.msgId 
    AND MailAssignments.forTeam <> '' 
WHERE Mails.msgId <= ? 
    AND MailAssignments.msgId IS NULL /* either no match for this mail at all 
             or no match with an existing assignment 
             – so, just no match */ 
+0

«MailAssignments.forTeam <> ''' отменяется таким образом, не так ли? –

+0

@ypercube: Да, запрос должен возвращать строки, в которых строка 'Mails' не имеет совпадения' MailAssignments', или ее совпадение имеет пустое значение 'forTeam' (либо' '' 'или' NULL'). –

+0

@ypercube: На самом деле я забыл указать, что именно нужно вернуть. :) Обновлен ответ сейчас. –

Смежные вопросы