今年需要吸引具有特定 activity 的客户(潜在客户),其中 activity(潜在客户)是他们的最后一个客户

Need to pull customers with specific activity this year (Leads), where that activity (Lead) was their last one

我正在使用 SSMS 创建一份报告,显示销售代表未跟进我们今年收到的潜在客户的客户帐户。这将在活动列表(帐户中的操作)中的帐户中指明,'Lead' 是列出的最后一个(代表在收到潜在客户后未采取任何操作)。

我的代码正在为今年至少有一个潜在客户的所有客户提取最新的 'Lead' activity:

CustomerName Activity Date
Bob's Tires Lead 2021-01-05
Ned's Nails Lead 2021-02-02
Good Eats Lead 2021-02-03

我需要它只将客户拉到最后一个潜在客户的位置 activity:

CustomerName Activity Date
Ned's Nails Lead 2021-02-02

这是我的代码和示例表。我错过了什么?我试过很多东西都没有运气。

WITH activities AS (
    SELECT 
        a. *
        , CASE WHEN a.ContactDate = MAX(CASE WHEN a.Activity LIKE 'Lead%'
               THEN a.ContactDate END) OVER (PARTITION BY a.AcctID)
          THEN 1 ELSE 0 END AS no_followup
    FROM AcctActivities a
    WHERE a.ContactDate >= '2021-01-01'
)
SELECT 
    c.Name,
    act.Activity,
    act.ContactDate
FROM Customers c
INNER JOIN activities act ON c.AcctID = act.AcctID AND act.no_followup = 1
ORDER BY c.AcctID, act.ContactDate ASC

Table 1: 客户 (c)

AcctID CustomerName
11 Bob's Tires
12 Ned's Nails
13 Good Eats
14 Embers

Table 2:活动(一)

AcctivityID AcctID Activity Date
1 11 Contact Added 2021-01-01
2 11 Lead 2021-01-05
3 11 Phone Call 2021-01-06
4 12 Lead 2021-02-02
5 13 Lead 2021-02-03
6 13 Phone Call 2021-01-15
7 13 Sales Email 2021-01-15
8 14 Cold Call 2021-01-20

我同意 Gordon 的观点,您的问题并不完全清楚(您实际上只关心今年的活动吗?no_followup 的预期含义是什么?)。话虽如此,我想这就是你想要的:

select      c.Name, 
            lastActivity.Activity, 
            lastActivity.ContactDate
from        Customers c
cross apply (
               select   top 1 a.Activity, a.ContactDate
               from     activities a 
               where    a.acctId = c.acctId 
                        -- and a.ContactDate >= '2021-01-01' uncomment this if you only care about activity this year
               order by a.ContactDate desc
            ) lastActivity
where       lastActivity.Activity like 'Lead%'

您的方法会过滤哪些行可能被视为比较中的最大值。我在下面包含了建议的修改,它还修改了您的 CASE 表达式以考虑当前行是一个潜在客户,因为 case 表达式可能会过滤要考虑的有界值(即它将为您提供最新的潜在客户 activity 但最新潜在客户 activity 可能不是您最新的 activity)。

另一个可能是可选但安全的修改是在分区的 OVER 子句中添加 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING。虽然您也可以使用 UNBOUNDED PRECEDING 而不是 CURRENT ROW,但当订购的 ContactDate 之前的所有行都已经小于当前值并且您感兴趣时,这似乎是额外的处理联系日期的最大值。 window 函数默认考虑当前和之前的所有行。该修正案将要求 window 函数查看当前行之后分区中的所有结果。

例如

WITH activities AS 
(
SELECT 
        a. *,
        CASE 
            WHEN a.Activity LIKE 'Lead%' AND
                 a.ContactDate = (MAX(a.ContactDate) OVER (PARTITION BY a.AcctID ORDER BY a.ContactDate ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING  ))
                THEN 1 
                ELSE 0
        END AS no_followup
    FROM 
        AcctActivities a
    WHERE 
        a.ContactDate >= '2021-01-01'

)
SELECT 
    c.Name,
    act.Activity,
    act.ContactDate
FROM 
    Customers c
INNER JOIN 
    activities act ON c.AcctID = act.AcctID
                   AND act.no_followup = 1
ORDER BY 
    c.AcctID, act.ContactDate ASC

此外,如果您只对客户详细信息感兴趣并且所有结果 activity 名称都是 Lead 您可以考虑使用以下方法,该方法使用聚合和 having 子句来过滤您想要的结果.这种方法 returns 通过早期过滤在生成的 CTE 中减少了细节。

WITH customers_with_last_activity_as_lead as (
    SELECT AcctID, MAX(ContactDate) as ContactDate
    FROM AcctActivities a
    WHERE a.ContactDate >= '2021-01-01'
    GROUP BY AcctID
    HAVING
        MAX(a.ContactDate) = MAX(
            CASE 
                 WHEN a.Activity LIKE 'Lead%' THEN a.ContactDate
            END
        )
)
SELECT 
    c.Name,
--  'Lead' as Activity, -- Uncomment this line if it is that you would like to see this constant value in your resulting queries.    
    act.ContactDate
FROM 
    Customers c
INNER JOIN 
   customers_with_last_activity_as_lead  act ON c.AcctID = act.AcctID
ORDER BY 
    c.AcctID, act.ContactDate ASC

如果所有值都不是 constant/literal Lead 那么以下方法可能有助于检索正确的 activity 名称

WITH customers_with_last_activity_as_lead as (
    SELECT 
        AcctID, 
        REPLACE(MAX(CONCAT(ContactDate,Activity)),MAX(ContactDate),'') as Activity,
        MAX(ContactDate) as ContactDate
    FROM AcctActivities a
    WHERE a.ContactDate >= '2021-01-01'
    GROUP BY AcctID
    HAVING
        MAX(a.ContactDate) = MAX(
            CASE 
                 WHEN a.Activity LIKE 'Lead%' THEN a.ContactDate
            END
        )
)
SELECT 
    c.Name,
    act.Activity, 
    act.ContactDate
FROM 
    Customers c
INNER JOIN 
   customers_with_last_activity_as_lead  act ON c.AcctID = act.AcctID
ORDER BY 
    c.AcctID, act.ContactDate ASC

让我知道这是否适合你.