2015-12-14 2 views
1

Требуется помощь SQL.SQL-запрос для получения набора результатов на основе внутреннего соединения

Столы

  • лицо (номер, имя)
  • Сообщение (идентификатор, текст)
  • PersonMsgResponse (MsgID, PersonId, delMethod, получил (Y/N)

Структура таблицы PersonMsgResponse

  • MessageID (MsgId)
  • PersonID (PerID)
  • MessageDeliveredBy (DelMethod)
  • Полученное (Y/N) (Получено)

Пример строки в таблице PersonMsgResponse таблице

Example Rows within PersonMsgResponse table

мне нужно верните список имен лиц, которые НЕ получили сообщение.

Как я могу заставить SQL возвращать имена членов для тех членов, которые не получили сообщение с помощью любого из методов?

Например, в списке записей выше мой запрос должен возвращать только член 1, так как член 2 получил сообщение посредством телефонного вызова, тогда как элемент 1 не получил сообщение с помощью какого-либо метода.

Благодарим за помощь.

ответ

2

Вы можете выполнить это с помощью двух внутренних запросов, как показано ниже. Трюк состоит в том, чтобы включить всех лиц, имеющих «N» в полученных, но не имеющих «Y». В этом примере таблица сообщений технически не нужна.

SELECT p.Name 
FROM Person p 
WHERE p.id IN ( 
        SELECT personID 
        FROM PersonMsgResponse pmr 
        WHERE pmr.received = 'N' AND pmr.personID NOT IN (SELECT personID FROM PersonMsgResponse pmr WHERE pmr.received = 'Y') 
       ) 

Это возвращает

Name 
person 1 
+0

Это сделало трюк с добавлением идентификатора сообщения. Окончательный запрос выглядел так: – Tim

+0

SELECT m.Person ID FROM Person p WHERE m.PersonID IN (SELECT MemberID FROM PersonMsgResponse pmr WHERE pmr.MessageID = 1 AND pmr.Received = 'N' И pmr.PersonID NOT IN (SELECT MemberID FROM PersonMsgResponse pmr WHERE pmrMessageID = 1 AND pmr.Received = 'Y')) – Tim

0

ОБНОВЛЕНО:

Вы можете использовать NOT EXISTS() подзапрос:

select MsgID, PerID from PersonMsgResponse p1 
inner join PersonMsgResponse p3 on p1.MsgID=p3.MsgId and p1.PerID=32.PerID and p3.Received='N' 
where not exists(select 1 from PersonMsgResponse p2 where p1.MsgID=p2.MsgId and p1.PerID=p2.PerID and p2.Received='Y') 

Если вы хотите имена из таблицы лиц, то только внутреннее соединение таблицы лиц, находящихся на p1.

+0

Это не работает, потому что она возвращает людей сообщение не было отправлено. – Tim

+0

@ Проверка проверки обновленного ответа – Shadow

1

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

SELECT Id, Name 
FROM Person AS p 
WHERE NOT EXISTS (SELECT 1 
        FROM PersonMsgResponse AS pmr 
        WHERE p.Id = pmr.personID AND p.Received = 'Y' AND 
         p.MessageID = 1) 
     AND EXISTS (SELECT 1 
        FROM PersonMsgResponse AS pmr 
        WHERE p.Id = pmr.personID AND p.MessageID = 1) 

Этот запрос возвращает список лиц, которые не получили сообщение с конкретных в любой из доступных методов.

+0

Это не работает, потому что оно возвращает людей, к которым сообщение не было отправлено. – Tim

+0

@Tim Проверьте редактирование, которое я сделал. –

0
select PersonTable.Person 
From  Person as PersonTable inner join PersonMsgResponse as ResponseTable 
     on PersonTable.Id = ResponseTable.PerId 
where ResponseTable.Received = 'n' 

добавить Distinct в оператор выбора, как так

Select Distinct (PersonTable.Person) 

Если вы не хотите неоднократного Лица

UPDATE

Вашего комментария, измените значение, так нет лицо может иметь «y» для полученных

select Distinct (PersonTable.Id) , PersonTable.Name, ResponseTable.Received 
From  Person as PersonTable inner join PersonMsgResponse as ResponseTable 
     on PersonTable.Id = ResponseTable.PerId 
where ResponseTable.Received != 'Y' 
+0

Это не работает, потому что оно возвращает людей, которым было отправлено сообщение, которое они открыли другим способом. – Tim

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