今年需要吸引具有特定 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
让我知道这是否适合你.
我正在使用 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
让我知道这是否适合你.