2016-08-08 2 views
0

Я присоединяюсь к нескольким таблицам. С одним из моих соединений (от 1 до многих) я хочу показать результаты, только если объединенная таблица имеет хотя бы одну строку, где существует определенное значение.SQL Server 2000 соединяется с условием подсчета

Этот пример исключает других соединений, поэтому для простоты:

SELECT 
    c.Name, r.RoleID, r.RoleName 
FROM 
    Contact c 
INNER JOIN 
    Role r ON r.ContactID = c.ID 

Контакт А может иметь много ролей. Я хочу показать все роли для контактов, но получить только контакты, в которых хотя бы одна роль имеет RoleID = 4. Я пробовал несколько вещей, но пока ничего не добился. Если это имеет значение, это на SQL Server 2000.

Я расширил масштабы этой проблемы в этот новый вопрос: SQL Server 2000 condition on joined table

+1

Sql Server 2000 - это минус конец жизни. Это означает, что он больше не получает никаких обновлений ... _ даже не критические исправления безопасности! Опасно и безответственно продолжать его использовать. Обновление этого сервера - задание # 1. –

+0

Я не мог согласиться с вами больше, и этот сервер должен быть обновлен другим отделом в конце года. – Kershaw

+0

Я включил проблему в этот новый вопрос: http://stackoverflow.com/questions/38839917/sql-server-2000-condition-on-joined-table – Kershaw

ответ

1

Сделайте соединение дважды, когда вы ограничиваете ID 4 в качестве фильтра, и снова, чтобы задействовать все роли:

SELECT 
    c.Name, r.RoleID, r.RoleName 
FROM 
    Contact c 
INNER JOIN --if a Contact does not match any Roles with ID 4, this join will exclude that contact from the results 
    Role rt /*role temp*/ ON rt.ContactID = c.ID AND rt.RoleId = 4   
INNER JOIN 
    Role r ON r.ContactID = c.ID 

Это делает одно допущение, которое прямо не указано в вопросе. Хотя контакт может иметь много ролей, это предполагает, что контакт не будет назначать одну и ту же роль более одного раза.

+0

Хорошая точка, и, фактически, контакт может иметь роль более одного раза, так как в записи роли есть другие свойства, которые бы отличали одни и те же роли для данного контакта. – Kershaw

+0

В таком случае лучше всего ждать обновления сервера, так как более новые версии Sql Server позволят вам использовать оператор APPLY для создания 1-го JOIN, который вы можете использовать, чтобы ограничить себя одним результатом. –

+0

Ну, на данный момент это не вариант. Я использую этот запрос для помощи в задаче, и эта задача уже просрочена! Thx для вашего ввода, это может привести меня к решению. – Kershaw

0

Вы можете использовать EXISTS:

SELECT 
    c.Name, r.RoleID, r.RoleName 
FROM 
    Contact c 
INNER JOIN 
    Role r ON r.ContactID = c.ID 
WHERE EXISTS(SELECT 1 FROM Role 
      WHERE RoleID = 4 
      AND ContactID = c.ID); 
+0

Ваше решение ТАКЖЕ работает, но когда я привожу другие таблицы для присоединения Я столкнулся с проблемами, когда не все возвращенные контакты имеют roleID = 4, но некоторые из них делают. Вы дали рабочий ответ на заданный вопрос и, следовательно, заслуживаете его. – Kershaw

0

А вы попробуйте

SELECT 
    c.Name, r.RoleID, r.RoleName 
FROM 
    Contact c 
INNER JOIN 
    Role r ON r.ContactID = c.ID group by c.Name, r.RoleID, r.RoleName having min(r.RoleID) = 4 
+0

Этот ответ ТОЛЬКО возвращает роли, где RoleID = 4, и другие роли. – Kershaw

+0

Вы можете использовать подобное ВЫБРАТЬ c.Name, r.RoleID, r.RoleName ОТ Связаться с INNER JOIN Роль г на r.ContactID = c.ID где c.ID в (SELECT г. ContactID FROM Роль r группа по r.ContactID с min (r.RoleID) = 4)) –

+0

RoleID начинается с 1, а Contact может иметь идентификаторы Role 1, 3, 4, 22 и т. Д. Итак, кажется что «с min (r.RoleID) = 4)« опускает контакты с RoleID <4? – Kershaw