dalongxia/sqlserver/shop_weekly_report.sql
2026-03-04 13:25:48 +08:00

112 lines
4.2 KiB
Transact-SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

USE [JSDataMiddlePlatform];
GO
/*
Template: 店铺周报
Window: 上一个自然周 [week_start, week_end)
*/
DECLARE @week_start datetime2 = CAST(DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()) - 1, 0) AS datetime2);
DECLARE @week_end datetime2 = CAST(DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()), 0) AS datetime2);
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,
TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined20, '')) AS qty,
TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined21, '')) AS goods_amount,
TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined22, '')) AS goods_cost,
TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined26, '')) AS payment_amount,
TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined29, '')) AS actual_amount,
TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined31, '')) AS actual_cost,
TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined47, '')) AS apply_amount,
TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined50, '')) AS return_amount,
TRY_CONVERT(decimal(18, 2), NULLIF(a.undefined52, '')) AS refund_amount,
ISNULL(NULLIF(a.undefined62, ''), '') AS order_labels,
a.createdAt AS created_at
INTO #base
FROM dbo.jst_goods_profit_kpi_items_afs AS a WITH (NOLOCK)
WHERE a.createdAt >= @week_start
AND a.createdAt < @week_end
AND ISNULL(NULLIF(a.undefined2, ''), '') <> ''
AND ISNULL(NULLIF(a.undefined62, ''), '') NOT LIKE '%配件%'
AND ISNULL(NULLIF(a.undefined62, ''), '') NOT LIKE '%特殊单%';
-- 1) 周总览
SELECT
@week_start AS week_start,
@week_end AS week_end,
COUNT(*) AS afs_record_count,
COUNT(DISTINCT order_id) AS order_count,
SUM(ISNULL(qty, 0)) AS qty_sum,
SUM(ISNULL(payment_amount, 0)) AS payment_amount,
SUM(ISNULL(actual_amount, 0)) AS actual_amount,
SUM(ISNULL(actual_cost, 0)) AS actual_cost,
SUM(ISNULL(refund_amount, 0)) AS refund_amount,
SUM(ISNULL(return_amount, 0)) AS return_amount
FROM #base;
-- 2) 平台周报
SELECT
platform_name,
COUNT(*) AS afs_record_count,
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,
SUM(ISNULL(actual_amount, 0)) - SUM(ISNULL(actual_cost, 0)) AS gross_profit
FROM #base
GROUP BY platform_name
ORDER BY payment_amount DESC;
-- 3) 店铺 TOP30
SELECT TOP (30)
shop_name,
platform_name,
COUNT(*) AS afs_record_count,
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,
SUM(ISNULL(actual_amount, 0)) - SUM(ISNULL(actual_cost, 0)) AS gross_profit,
CASE
WHEN SUM(ISNULL(actual_amount, 0)) = 0 THEN NULL
ELSE (SUM(ISNULL(actual_amount, 0)) - SUM(ISNULL(actual_cost, 0))) / SUM(ISNULL(actual_amount, 0))
END AS gross_margin_rate
FROM #base
GROUP BY shop_name, platform_name
ORDER BY payment_amount 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
AND CASE
WHEN SUM(ISNULL(payment_amount, 0)) = 0 THEN 0
ELSE SUM(ISNULL(refund_amount, 0)) / SUM(ISNULL(payment_amount, 0))
END >= 0.15
ORDER BY refund_rate DESC, payment_amount DESC;