根据特定条件返回具有最大日期的记录

时间:2015-12-11 19:16:16

标签: sql sql-server-2008 tsql

我正在尝试从包含“活动”的表中为客户编写查询。每个活动都存储在一行中,因此如果您呼叫联系人并在之后发送电子邮件,它将分为两行。

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

我想返回最近的通话记录,如果没有通话,则是最新的电子邮件。

所以输出会像这样返回:

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

这是我写的当前查询:

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)

这里有什么想法吗?

3 个答案:

答案 0 :(得分:1)

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

根据您想要的结果,我假设您正在寻找每个call/email组合的最新contact/employee记录。如果这不完全正确,您只需要在查询中调整partition by子句。

答案 1 :(得分:0)

谢谢sstan;这就是我完成的事情:

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

与员工是谁进行联系并不重要,只是联系是与列表中的个人联系,所以我从分区中删除了

答案 2 :(得分:0)

考虑没有窗口函数的UNION查询。下面按数据版本类型细分,因为您发布的版本与实际数据不完全匹配。

您的简化发布数据版本:

-- 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

实际数据版本(可能需要调整)

-- 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