#sql #tsql
#sql #tsql
Вопрос:
У меня есть таблица SQL (Email_Campaigns) с основным списком кампаний, которые мы запустили:
Name DateSent
Campaign01 01/01/2011
Campaign02 01/15/2011
..
Campaign40 10/01/2011
У меня есть список клиентов (Email_Received) с их номерами участников и кампаниями, которые они получили:
PK MembershipNo CampaignName
1 123456 Campaign01
2 123456 Campaign02
3 987654 Campaign05
4 111111 Campaign10
У меня также есть основной список клиентов MembershipNo (клиенты)
Вопрос: Как мне написать запрос, чтобы перечислить каждую кампанию и подсчитать количество клиентов, которые НЕ получили это электронное письмо? Например (столбец ‘Received’ показан здесь только для справки и не является обязательным, поскольку я знаю, как это вычислить):
Name Received DidNotReceive
Campaign01 1000 9000
Campaign02 3000 7000
..
Campaign40 100 9900
Комментарии:
1. Чтобы ответить на вопрос ниже… Да, безусловно, бывают случаи, когда клиенты получали несколько сообщений электронной почты, и это сделано специально.
Ответ №1:
Вот один из стандартных способов SQL для записи этого:
SELECT ec.Name, count(c.MembershipNo) AS DidNotReceive
FROM Customers AS c
, Email_Campaigns AS ec
WHERE NOT EXISTS (
SELECT 1
FROM Email_Received AS r
WHERE er.CampaignName = ec.CampaignName
AND er.MembershipNo = c.MembershipNo)
GROUP BY ec.Name
ORDER BY ec.Name;
Комментарии:
1. Спасибо! Я рад, что спросил, потому что раньше у меня было именно то, что у вас было, за исключением предложения «И»… неудивительно, что запрос вращался более 15 минут без результата. :-/
2. @hurleystylee: если это позволяют ваши конкретные условия, вам также следует попробовать ответ Джо Стефанелли, который может быть значительно быстрее с большими таблицами. При необходимости добавьте то
DISTINCT
, что я упомянул.
Ответ №2:
SELECT er.CampaignName,
COUNT(*) AS Received,
(SELECT COUNT(*) FROM Customers) - COUNT(*) AS DidNotReceive
FROM Email_Received er
GROUP BY er.CampaignName
ORDER BY er.CampaignName;
Это на самом простом уровне. Вероятно, следует учитывать дополнительные соображения, например, был ли данный клиент активен во время распространения кампании.
Комментарии:
1. Это должно быть быстрее, чем мой ответ. Однако мой ответ также охватывает случай дублирования записей в
Email_Received
(люди могут получать несколько электронных писем, по замыслу или по ошибке), что не было исключено в вопросе. Может быть исправлено с помощью COUNT (DISTINCT x). Не уверен, разрешено ли это в tsql.2. @ErwinBrandstetter T-SQL имеет
COUNT(DISTINCT x)
.