На работе одно из моих заданий - рассчитать комиссию для торгового персонала. Одно правило было более сложным, чем другие.Использовать рекурсивный CTE для обработки логики даты
Две команды продаж A и B работают вместе, продавая разные продукты. Команда A может отправлять команды в команду B. Один и тот же клиент может отправлять несколько раз. В первый раз, когда клиент (например, 1-й свинец) * отправляет комиссию, выплачивается продавцу в команде A, который создал лидирующую позицию. Теперь клиент «заблокирован» в течение следующих 365 дней (считая с даты, когда был создан свинец 1) . Это означает, что никто не может получить дополнительную комиссию для этого клиента в этот период, отправив дополнительные лидеры (например, Lead 2 и 3 не получает комиссионных). По истечении 365 дней. Новое руководство может быть создано и получить комиссию (например, руководство 4). Затем клиент снова блокируется в течение 365 дней, считая с того дня, когда был создан вывод 4. Поэтому руководство 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 для образца данные, пожалуйста, напишите свой ожидаемый результат. – TheGameiswar
Последний столбец в образцах данных является желаемым результатом. Спасибо за ваше время. –
В вашем запросе есть некоторые проблемы, вы можете вставить ожидаемый результат в вопрос – TheGameiswar