162 lines
5.2 KiB
Transact-SQL
162 lines
5.2 KiB
Transact-SQL
USE [JSDataMiddlePlatform];
|
||
GO
|
||
|
||
/*
|
||
Template: 退款原因分析
|
||
Window: 最近30天 [date_from, date_to)
|
||
*/
|
||
|
||
DECLARE @date_from datetime2 = CAST(DATEADD(DAY, -30, CAST(GETDATE() AS date)) AS datetime2);
|
||
DECLARE @date_to datetime2 = CAST(DATEADD(DAY, 1, CAST(GETDATE() AS date)) AS datetime2);
|
||
|
||
IF OBJECT_ID('tempdb..#chat_latest') IS NOT NULL
|
||
DROP TABLE #chat_latest;
|
||
|
||
WITH chat_rank AS (
|
||
SELECT
|
||
NULLIF(c.orderNo, '') AS order_id,
|
||
ISNULL(NULLIF(c.mainReason, ''), '') AS main_reason,
|
||
ISNULL(NULLIF(c.secondReason, ''), '') AS second_reason,
|
||
ISNULL(NULLIF(c.thirdReason, ''), '') AS third_reason,
|
||
ROW_NUMBER() OVER (
|
||
PARTITION BY NULLIF(c.orderNo, '')
|
||
ORDER BY c.createdAt DESC, c.id DESC
|
||
) AS rn
|
||
FROM dbo.pc_kfChatLog AS c WITH (NOLOCK)
|
||
WHERE c.createdAt >= @date_from
|
||
AND c.createdAt < @date_to
|
||
AND ISNULL(NULLIF(c.orderNo, ''), '') <> ''
|
||
)
|
||
SELECT
|
||
order_id,
|
||
main_reason,
|
||
second_reason,
|
||
third_reason
|
||
INTO #chat_latest
|
||
FROM chat_rank
|
||
WHERE rn = 1;
|
||
|
||
IF OBJECT_ID('tempdb..#base') IS NOT NULL
|
||
DROP TABLE #base;
|
||
|
||
SELECT
|
||
NULLIF(a.undefined2, '') AS order_id,
|
||
COALESCE(NULLIF(a.undefined8, ''), 'unknown') AS shop_name,
|
||
CASE
|
||
WHEN CHARINDEX('-', ISNULL(a.undefined8, '')) > 1
|
||
THEN LEFT(a.undefined8, CHARINDEX('-', a.undefined8) - 1)
|
||
ELSE 'unknown'
|
||
END AS platform_name,
|
||
ISNULL(NULLIF(a.undefined56, ''), '未标注') AS afs_type,
|
||
ISNULL(NULLIF(a.undefined57, ''), '') AS native_afs_reason,
|
||
ISNULL(cl.main_reason, '') AS chat_main_reason,
|
||
ISNULL(cl.second_reason, '') AS chat_second_reason,
|
||
ISNULL(cl.third_reason, '') AS chat_third_reason,
|
||
CASE
|
||
WHEN ISNULL(NULLIF(a.undefined57, ''), '') <> '' THEN ISNULL(NULLIF(a.undefined57, ''), '')
|
||
WHEN ISNULL(cl.main_reason, '') <> '' THEN cl.main_reason
|
||
ELSE '未标注'
|
||
END AS afs_reason_l1,
|
||
CASE
|
||
WHEN ISNULL(cl.second_reason, '') <> '' THEN cl.second_reason
|
||
ELSE '未标注'
|
||
END AS afs_reason_l2,
|
||
CASE
|
||
WHEN ISNULL(cl.third_reason, '') <> '' THEN cl.third_reason
|
||
ELSE '未标注'
|
||
END AS afs_reason_l3,
|
||
CASE
|
||
WHEN ISNULL(NULLIF(a.undefined57, ''), '') <> '' THEN 'afs_reason'
|
||
WHEN ISNULL(cl.main_reason, '') <> '' THEN 'chat_main_reason'
|
||
ELSE 'unknown'
|
||
END AS reason_source,
|
||
ISNULL(NULLIF(a.undefined58, ''), '未标注') AS afs_result,
|
||
TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined50, '')) AS return_amount,
|
||
TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined52, '')) AS refund_amount,
|
||
TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined26, '')) AS payment_amount,
|
||
ISNULL(NULLIF(a.undefined62, ''), '') AS order_labels
|
||
INTO #base
|
||
FROM dbo.jst_goods_profit_kpi_items_afs AS a WITH (NOLOCK)
|
||
LEFT JOIN #chat_latest AS cl
|
||
ON cl.order_id = NULLIF(a.undefined2, '')
|
||
WHERE a.createdAt >= @date_from
|
||
AND a.createdAt < @date_to
|
||
AND ISNULL(NULLIF(a.undefined2, ''), '') <> ''
|
||
AND ISNULL(NULLIF(a.undefined62, ''), '') NOT LIKE '%配件%'
|
||
AND ISNULL(NULLIF(a.undefined62, ''), '') NOT LIKE '%特殊单%';
|
||
|
||
-- 1) 全局退款原因 TOP30
|
||
SELECT TOP (30)
|
||
afs_reason_l1 AS afs_reason,
|
||
reason_source,
|
||
COUNT(*) AS afs_record_count,
|
||
COUNT(DISTINCT order_id) AS order_count,
|
||
SUM(ISNULL(refund_amount, 0)) AS refund_amount,
|
||
SUM(ISNULL(return_amount, 0)) AS return_amount,
|
||
CASE
|
||
WHEN SUM(ISNULL(payment_amount, 0)) = 0 THEN NULL
|
||
ELSE SUM(ISNULL(refund_amount, 0)) / SUM(ISNULL(payment_amount, 0))
|
||
END AS reason_refund_rate
|
||
FROM #base
|
||
GROUP BY afs_reason_l1, reason_source
|
||
ORDER BY afs_record_count DESC;
|
||
|
||
-- 2) 平台内原因 TOP10
|
||
WITH reason_rank AS (
|
||
SELECT
|
||
platform_name,
|
||
afs_reason_l1 AS afs_reason,
|
||
COUNT(*) AS afs_record_count,
|
||
SUM(ISNULL(refund_amount, 0)) AS refund_amount,
|
||
ROW_NUMBER() OVER (
|
||
PARTITION BY platform_name
|
||
ORDER BY COUNT(*) DESC
|
||
) AS rn
|
||
FROM #base
|
||
GROUP BY platform_name, afs_reason_l1
|
||
)
|
||
SELECT
|
||
platform_name,
|
||
afs_reason,
|
||
afs_record_count,
|
||
refund_amount
|
||
FROM reason_rank
|
||
WHERE rn <= 10
|
||
ORDER BY platform_name, afs_record_count DESC;
|
||
|
||
-- 3) 二级原因 TOP20(可用于更细分原因)
|
||
SELECT TOP (20)
|
||
afs_reason_l1,
|
||
afs_reason_l2,
|
||
COUNT(*) AS afs_record_count,
|
||
SUM(ISNULL(refund_amount, 0)) AS refund_amount
|
||
FROM #base
|
||
GROUP BY afs_reason_l1, afs_reason_l2
|
||
ORDER BY afs_record_count DESC;
|
||
|
||
-- 4) 店铺退款风险清单(订单数>=50)
|
||
SELECT
|
||
shop_name,
|
||
platform_name,
|
||
COUNT(DISTINCT order_id) AS order_count,
|
||
SUM(ISNULL(payment_amount, 0)) AS payment_amount,
|
||
SUM(ISNULL(refund_amount, 0)) AS refund_amount,
|
||
CASE
|
||
WHEN SUM(ISNULL(payment_amount, 0)) = 0 THEN NULL
|
||
ELSE SUM(ISNULL(refund_amount, 0)) / SUM(ISNULL(payment_amount, 0))
|
||
END AS refund_rate
|
||
FROM #base
|
||
GROUP BY shop_name, platform_name
|
||
HAVING COUNT(DISTINCT order_id) >= 50
|
||
ORDER BY refund_rate DESC, payment_amount DESC;
|
||
|
||
-- 5) 售后类型/结果矩阵
|
||
SELECT
|
||
afs_type,
|
||
afs_result,
|
||
COUNT(*) AS afs_record_count,
|
||
SUM(ISNULL(refund_amount, 0)) AS refund_amount
|
||
FROM #base
|
||
GROUP BY afs_type, afs_result
|
||
ORDER BY afs_record_count DESC;
|