【发布时间】:2017-03-30 17:53:51
【问题描述】:
在工作中,我的一项任务是计算销售人员的佣金。一项规则比其他规则更具挑战性。
两个销售团队 A 和 B 一起工作,各自销售不同的产品。 A 团队可以将潜在客户发送给 B 团队。同一个客户可能会被多次发送。首次向客户(例如潜在客户 1)* 发送佣金时,将向 A 团队中创建潜在客户的销售人员支付佣金。现在,客户在接下来的 365 天内被“锁定”(从创建线索 1 的日期算起)。这意味着在此期间,没有人可以通过发送额外的线索为该客户获得额外的佣金(例如,线索 2 和 3 没有佣金)。 365 天到期后。可以创建新的潜在客户并获得佣金(例如潜在客户 4)。然后,从创建线索 4 之日算起,客户再次被锁定 365 天。因此,lead 5 没有佣金。棘手的部分是重置计算 365 天的日期。
'* 引用表#LEADS 和#DISERED 结果。
我已经使用游标解决了 tSQL 中的问题,但我想知道是否可以使用递归 CTE。我做了几次尝试,最好的一个贴在下面。我的解决方案的问题是,我不止一次引用递归表。我试图通过在 CTE 中嵌套 CTE 来解决这个问题。这是不允许的。我曾尝试在 CTE 中使用一个临时表,这也是不允许的。我尝试了几次重新编码 CTE 的递归部分,以便递归表只被引用一次,但是我无法让逻辑工作。
我正在使用 SQL 2008
IF OBJECT_ID('tempdb.dbo.#LEADS', 'U') IS NOT NULL
DROP TABLE #LEADS;
CREATE TABLE #LEADS (LEAD_ID INT, CUSTOMER_ID INT, LEAD_CREATED_DATE DATETIME, SALESPERSON_NAME varchar(20))
INSERT INTO #LEADS
VALUES (1, 1, '2013-09-01', 'Rasmus')
,(2, 1, '2013-11-01', 'Christian')
,(3, 1, '2014-01-01', 'Nadja')
,(4, 1, '2014-12-24', 'Roar')
,(5, 1, '2015-12-01', 'Kristian')
,(6, 2, '2014-01-05', 'Knud')
,(7, 2, '2015-01-02', 'Rasmus')
,(8, 2, '2015-01-08', 'Roar')
,(9, 2, '2016-02-05', 'Kristian')
,(10, 2, '2016-03-05', 'Casper')
SELECT *
FROM #LEADS;
IF OBJECT_ID('tempdb.dbo.#DISERED_RESULT', 'U') IS NOT NULL
DROP TABLE #DISERED_RESULT;
CREATE TABLE #DISERED_RESULT (LEAD_ID INT, DESIRED_COMMISION_RESULT CHAR(3))
INSERT INTO #DISERED_RESULT
VALUES (1, 'YES')
,(2, 'NO')
,(3, 'NO')
,(4, 'YES')
,(5, 'NO')
,(6, 'YES')
,(7, 'NO')
,(8, 'YES')
,(9, 'YES')
,(10, 'NO')
SELECT *
FROM #DISERED_RESULT;
WITH COMMISSION_CALCULATION AS
(
SELECT T1.*
,COMMISSION = 'YES'
,MIN_LEAD_CREATED_DATE AS COMMISSION_DATE
FROM #LEADS AS T1
INNER JOIN (
SELECT A.CUSTOMER_ID
,MIN(A.LEAD_CREATED_DATE) AS MIN_LEAD_CREATED_DATE
FROM #LEADS AS A
GROUP BY A.CUSTOMER_ID
) AS T2 ON T1.CUSTOMER_ID = T2.CUSTOMER_ID AND T1.LEAD_CREATED_DATE = T2.MIN_LEAD_CREATED_DATE
UNION ALL
SELECT T10.LEAD_ID
,T10.CUSTOMER_ID
,T10.LEAD_CREATED_DATE
,T10.SALESPERSON_NAME
,T10.COMMISSION
,T10.COMMISSION_DATE
FROM (SELECT ROW_NUMBER() OVER(PARTITION BY T5.CUSTOMER_ID ORDER BY T5.LEAD_CREATED_DATE ASC) AS RN
,T5.*
,T6.MAX_COMMISSION_DATE
,DATEDIFF(DAY, T6.MAX_COMMISSION_DATE, T5.LEAD_CREATED_DATE) AS ANTAL_DAGE_SIDEN_SIDSTE_COMMISSION
,CASE
WHEN DATEDIFF(DAY, T6.MAX_COMMISSION_DATE, T5.LEAD_CREATED_DATE) > 365 THEN 'YES'
ELSE 'NO'
END AS COMMISSION
,CASE
WHEN DATEDIFF(DAY, T6.MAX_COMMISSION_DATE, T5.LEAD_CREATED_DATE) > 365 THEN T5.LEAD_CREATED_DATE
ELSE NULL
END AS COMMISSION_DATE
FROM #LEADS AS T5
INNER JOIN (SELECT T4.CUSTOMER_ID
,MAX(T4.COMMISSION_DATE) AS MAX_COMMISSION_DATE
FROM COMMISSION_CALCULATION AS T4
GROUP BY T4.CUSTOMER_ID) AS T6 ON T5.CUSTOMER_ID = T6.CUSTOMER_ID
WHERE T5.LEAD_ID NOT IN (SELECT LEAD_ID FROM COMMISSION_CALCULATION)
) AS T10
WHERE RN = 1
)
SELECT *
FROM COMMISSION_CALCULATION;
【问题讨论】:
-
样本数据加1,请发布您的预期结果
-
样本数据的最后一列是想要的结果。感谢您的宝贵时间。
-
您的查询有一些问题,您能否在问题中粘贴预期结果
-
我在原始问题中添加了一个新表,并获得了所需的结果。
-
我对这种说法感到困惑。 " 如果第二个潜在客户是在第一个潜在客户的 365 天之后创建的,那么客户将获得佣金。第二个潜在客户将在接下来的 365 天获得所有佣金。"
标签: sql sql-server sql-server-2008 tsql common-table-expression