Существуют две таблицы, таблица Contact
и таблица RelationshipHistory
.
Контакты могут иметь несколько типов отношений (Бизнес, Индивидуальный, Добровольцы и т.д.), Что означает, что они могут иметь несколько ссылок в таблице RelationshipHistory с течением времени. Каждая строка отношений имеет столбец, указывающий событие, с которым связано отношение. Так, например, контакт Джона Смита с ContactID 123 может иметь две строки в таблице RelationshipHistory: 123, Individual, Fun Event и 123, Volunteer, Boring Event. Запрос, который мне нужно выполнить, - "Получить все контакты, которые имеют отношения с событием" Событие Fun "и событие" Boring Event ".
Первоначально я думал, что такой запрос будет работать:
SELECT DISTINCT LastName, FirstName
FROM Contacts
JOIN RelationshipHistory ON RelationshipHistory.ContactKey = Contacts.ContactGUID
WHERE RelationshipHistory.Event = 'Fun Event'
AND RelationshipHistory.Event = 'Boring Event'
Но он не возвращает никаких результатов. Когда я просмотрел второй запрос, я понял, что это невозможно, потому что сравнение происходит по строкам, и не имеет смысла, чтобы значение в столбце равнялось двум различным значениям одновременно.
Запрос казался достаточно простым, но более пристально рассматривая его, я не могу найти строки, которые имеют соответствующие значения в столбце для двух или более значений.
Есть ли способ использовать внутренний выбор или объединение, или мне нужно сбрасывать результаты во временную таблицу...?
Если вам нужны контакты, которые имеют отношения как с Fun Event, так и с Boring Event:
SELECT DISTINCT LastName, FirstName FROM Contacts JOIN RelationshipHistory AS BoringEvent ON Boring.ContactKey = Contacts.ContactGUID JOIN RelationshipHistory AS FunEvent ON Boring.ContactKey = Contacts.ContactGUID WHERE FunEvent.Event = 'Fun Event' AND BoringEvent.Event = 'Boring Event'
Мы делаем два объединения с одной таблицей.
Использование:
SELECT LastName, FirstName
FROM Contacts c
JOIN RelationshipHistory re ON re.ContactKey = c.ContactGUID
AND re.Event IN ('Fun Event', 'Boring Event')
GROUP BY LastName, FirstName
HAVING COUNT(DISTINCT re.contactkey) = 2
Ваш запрос не работает, потому что он ожидает, что RELATIONSHIPHISTORY.contactkey
будет обоими значениями, что невозможно. Это означает, что вам нужно использовать OR
или использовать предложение IN
, которое является сокращением для нескольких ORs в одном столбце. Тем не менее, предложение IN не поддерживает какой-либо способ сопоставления шаблонов - вам нужно будет использовать полнотекстовый поиск (FTS) для этого...
Другая часть этого запроса - это предложение HAVING
- оно подсчитывает разные значения contactkey
, потому что, если они не были разными, дубликаты "Fun Event" будут ложными.
Для того, чтобы запрос работал, количество предложений IN должно соответствовать количеству различных подсчитываемых значений. Поэтому, если у вас есть три или пять событий для поиска, необходимо обновить предложение HAVING.
ON
действительно имеет значение только для OUTER-соединений, но я стараюсь быть последовательным. Для соединения OUTER предложение IN будет применено перед соединением - как производная таблица / встроенное представление.