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

96 lines
3.7 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: 物流时效/SLA分析
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..#base') IS NOT NULL
DROP TABLE #base;
SELECT
e.so_id AS order_id,
ISNULL(NULLIF(e.shop_name, ''), 'unknown') AS shop_name,
ISNULL(NULLIF(e.platform_name, ''), 'unknown') AS platform_name,
ISNULL(NULLIF(e.logistic_company_name, ''), 'unknown') AS logistic_company_name,
ISNULL(NULLIF(e.logistic_status_name, ''), 'unknown') AS logistic_status_name,
e.pay_time,
e.send_time,
e.fetch_time,
e.sign_time,
TRY_CONVERT(decimal(18, 4), e.weight) AS weight,
TRY_CONVERT(decimal(18, 4), e.f_weight) AS f_weight,
CASE
WHEN e.pay_time IS NOT NULL AND e.send_time IS NOT NULL
THEN DATEDIFF(HOUR, e.pay_time, e.send_time)
ELSE NULL
END AS pay_to_send_h,
CASE
WHEN e.send_time IS NOT NULL AND e.sign_time IS NOT NULL
THEN DATEDIFF(HOUR, e.send_time, e.sign_time)
ELSE NULL
END AS send_to_sign_h,
CASE
WHEN e.pay_time IS NOT NULL AND e.sign_time IS NOT NULL
THEN DATEDIFF(HOUR, e.pay_time, e.sign_time)
ELSE NULL
END AS pay_to_sign_h
INTO #base
FROM dbo.jst_order_express_details AS e WITH (NOLOCK)
WHERE e.createdAt >= @date_from
AND e.createdAt < @date_to
AND ISNULL(NULLIF(e.so_id, ''), '') <> ''
AND ISNULL(NULLIF(e.order_labels, ''), '') NOT LIKE '%配件%'
AND ISNULL(NULLIF(e.order_labels, ''), '') NOT LIKE '%特殊单%';
-- 1) 全局时效总览
SELECT
@date_from AS date_from,
@date_to AS date_to,
COUNT(*) AS order_count,
SUM(CASE WHEN sign_time IS NOT NULL THEN 1 ELSE 0 END) AS signed_order_count,
AVG(CASE WHEN pay_to_send_h >= 0 THEN CAST(pay_to_send_h AS decimal(18, 2)) END) AS avg_pay_to_send_h,
AVG(CASE WHEN send_to_sign_h >= 0 THEN CAST(send_to_sign_h AS decimal(18, 2)) END) AS avg_send_to_sign_h,
AVG(CASE WHEN pay_to_sign_h >= 0 THEN CAST(pay_to_sign_h AS decimal(18, 2)) END) AS avg_pay_to_sign_h
FROM #base;
-- 2) 平台时效
SELECT
platform_name,
COUNT(*) AS order_count,
AVG(CASE WHEN pay_to_send_h >= 0 THEN CAST(pay_to_send_h AS decimal(18, 2)) END) AS avg_pay_to_send_h,
AVG(CASE WHEN send_to_sign_h >= 0 THEN CAST(send_to_sign_h AS decimal(18, 2)) END) AS avg_send_to_sign_h,
SUM(CASE WHEN pay_to_send_h > 48 THEN 1 ELSE 0 END) AS delayed_send_over_48h,
SUM(CASE WHEN send_to_sign_h > 120 THEN 1 ELSE 0 END) AS delayed_sign_over_120h
FROM #base
GROUP BY platform_name
ORDER BY order_count DESC;
-- 3) 店铺时效预警(订单数>=100)
SELECT TOP (50)
shop_name,
platform_name,
COUNT(*) AS order_count,
AVG(CASE WHEN pay_to_send_h >= 0 THEN CAST(pay_to_send_h AS decimal(18, 2)) END) AS avg_pay_to_send_h,
AVG(CASE WHEN send_to_sign_h >= 0 THEN CAST(send_to_sign_h AS decimal(18, 2)) END) AS avg_send_to_sign_h,
SUM(CASE WHEN pay_to_send_h > 48 THEN 1 ELSE 0 END) AS delayed_send_over_48h,
SUM(CASE WHEN send_to_sign_h > 120 THEN 1 ELSE 0 END) AS delayed_sign_over_120h
FROM #base
GROUP BY shop_name, platform_name
HAVING COUNT(*) >= 100
ORDER BY delayed_send_over_48h DESC, avg_send_to_sign_h DESC;
-- 4) 快递公司表现
SELECT TOP (30)
logistic_company_name,
COUNT(*) AS order_count,
AVG(CASE WHEN send_to_sign_h >= 0 THEN CAST(send_to_sign_h AS decimal(18, 2)) END) AS avg_send_to_sign_h,
SUM(CASE WHEN send_to_sign_h > 120 THEN 1 ELSE 0 END) AS delayed_sign_over_120h
FROM #base
GROUP BY logistic_company_name
ORDER BY order_count DESC;