简体   繁体   English

根据某些条件返回具有最大日期的记录

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM