[英]Return record with the max date based on certain criteria
I am trying to write a query from a table that contains 'Activities' for customers. 我正在尝试从包含针对客户的“活动”的表中编写查询。 Each activity is stored in a single line so if you call a contact and send an email after, it will be in two separate rows.
每个活动都存储在一行中,因此,如果您呼叫联系人并在之后发送电子邮件,则它将分为两行。
ie 即
Contact Employee Date Method
Jack John 12/7/15 11:50 Email
Jack John 12/7/15 11:45 Email
Jill John 12/4/15 10:19 Call
Rick Amber 12/8/15 9:40 Call
Dave Sarah 12/10/15 17:10 Email
Dave Sarah 12/10/15 17:15 Call
Dave Sarah 12/10/15 17:20 Email
I would like to return the most recent record for the call and if there isn't a call, then the most recent email. 我想返回通话的最新记录,如果没有通话,则返回最近的电子邮件。
So the output would return like this: 因此输出将返回如下:
Contact Employee Date Method
Jack John 12/7/15 11:50 Email
Jill John 12/4/15 10:19 Call
Rick Amber 12/8/15 9:40 Call
Dave Sarah 12/10/15 17:15 Call
This is the current query I have written: 这是我写的当前查询:
select FA.ContactID,
FA.Employee as [ContactedBy],
FA.CreatedDate as [ContactedDate],
case when max(FA.CreatedDate) and FA.PrincipalCall = 1 then 'Call'
when max(FA.CreatedDate) and FA.PrincipalCall = 0 and FA.InboundEmail = 1 then 'Call & Email'
end as [ContactMethod]
from WorkingData.dbo.FactActivities FA
where FA.CreatedDate >= CAST('12-04-2015' as date)
and (FA.PrincipalCall = 1 or FA.InboundEmail = 1)
Any ideas here? 这里有什么想法吗?
The row_number
window function can help here: row_number
窗口函数可以在此处提供帮助:
select t.contact, t.employee, t.date, t.method
from (select *,
row_number() over (partition by contact, employee
order by
case when method = 'Call' then 0 else 1 end,
date desc) as rn
from WorkingData.dbo.FactActivities) t
where t.rn = 1
Based on your desired results, I am assuming that you are looking for the latest call/email
record for every contact/employee
combination. 根据您期望的结果,我假设您正在寻找每个
contact/employee
组合的最新call/email
记录。 If this is not exactly right, you just need to tweak the partition by
clause in the query. 如果这不完全正确,则只需调整查询中的
partition by
子句。
thanks to sstan; 多亏了斯坦 this is what I finished with:
这是我完成的工作:
select t.ContactID, t.Priority, t.ContactedBy, t.ContactedDate, t.ContactMethod
from (select FA.ContactID,
case when FA.PriorityLevel is null then 2 else FA.PriorityLevel end as [Priority],
FA.Employee as [ContactedBy],
FA.CreatedDate as [ContactedDate],
case when FA.PrincipalCall = 1 then 'Call'
when FA.InboundEmail = 1 then 'Email'
when FA.PrincipalCall = 1 and FA.InboundEmail = 1 then 'Call & Email'
end as [ContactMethod],
row_number() over (partition by FA.ContactID
order by case when FA.PrincipalCall = 1 then 0 else 1 end,
FA.CreatedDate desc) as rn
from WorkingData.dbo.FactActivities FA
where FA.CreatedDate >= CAST('12-04-2015' as date)
and (FA.PrincipalCall = 1 or FA.InboundEmail = 1)) t
where t.rn = 1
it doesn't matter who the employee was that made the contact, just that the contact was made with an individual on the list so i removed that from the partition 与谁联系的员工无关紧要,只是联系是与列表中的某人联系的,所以我从分区中删除了该联系
Consider a UNION query without window functions. 考虑不带窗口功能的UNION查询。 Below breaks down by data version type as your posted version does not fully match actual data.
下面按数据版本类型进行了细分,因为您发布的版本与实际数据不完全匹配。
Your simplified posted data version: 您的简化过帐数据版本:
-- AGGREGATE FOR CALLS
SELECT TableName.Contact, TableName.Employee,
Max(TableName.Date) AS MaxOfDate, TableName.Method
FROM TableName
WHERE TableName.Method = 'Call'
GROUP BY TableName.Contact, TableName.Employee,
TableName.Method
UNION
-- AGGREGATE FOR EMAILS (WITH NO CALLS)
SELECT TableName.Contact, TableName.Employee,
Max(TableName.Date) AS MaxOfDate, TableName.Method
FROM TableName
WHERE TableName.Method = 'Email'
GROUP BY TableName.Contact, TableName.Employee,
TableName.Method
HAVING (SELECT Count(*)
FROM TableName t2
WHERE t2.Method = 'Call'
AND t2.Contact = TableName.Contact
AND t2.Employee = TableName.Employee) = 0
Actual data version (might need adjusting) : 实际数据版本(可能需要调整) :
-- AGGREGATE FOR CALLS
SELECT FA.ContactID,
FA.Employee AS [ContactedBy],
Max(FA.CreatedDate) AS [ContactedDate],
'Call' AS [ContactMethod]
FROM WorkingData.dbo.FactActivities FA
WHERE FA.PrincipalCall = 1 AND FA.CreatedDate >= CAST('12-04-2015' as date)
GROUP BY FA.ContactID,
FA.Employee
ORDER BY FA.ContactID
UNION
-- AGGREGATE FOR EMAILS (WITH NO CALLS)
SELECT FA.ContactID,
FA.Employee AS [ContactedBy],
Max(FA.CreatedDate) AS [ContactedDate],
'Email' AS [ContactMethod]
FROM WorkingData.dbo.FactActivities FA
WHERE FA.InboundEmail = 1 AND FA.CreatedDate >= CAST('12-04-2015' as date)
GROUP BY FA.ContactID,
FA.Employee
HAVING
(SELECT Count(*)
FROM WorkingData.dbo.FactActivities FA t2
WHERE t2.PrincipalCall = 1 AND FA.CreatedDate >= CAST('12-04-2015' as date)
AND t2.ContactID = FA.ContactID
AND t2.Employee = FA.Employee) = 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.