上传源代码版本

This commit is contained in:
Im-Jenisson
2026-06-01 16:30:29 +08:00
commit b2a9b7d3c2
462 changed files with 104365 additions and 0 deletions

201
customer-daily-stats.sql Normal file
View File

@@ -0,0 +1,201 @@
-- 客户维度每日标签统计查询(不关联订单表)
-- 设计逻辑:
-- 1. 基于 label_scan_history、customers 两表关联
-- 2. 统计维度客户简称、日期、扫描数、换单成功数、换单失败数、STOP数等
WITH
-- 步骤1获取客户信息
CustomerInfo AS (
SELECT
c.id AS CustomerId,
c.CustomerCode,
c.CustomerName
FROM customers c
WHERE c.Status = 'Y'
),
-- 步骤2关联扫描记录与客户信息
ScanWithCustomer AS (
SELECT
s.NeutralWaybillNumber,
s.CustomerId AS ScanCustomerId,
DATE(CONVERT_TZ(s.CreatedAt, '+00:00', '-05:00')) AS ,
s.Result,
s.Description,
s.CreatedAt AS ,
c.CustomerCode,
c.CustomerName
FROM label_scan_history s
LEFT JOIN CustomerInfo c ON s.CustomerId = c.CustomerId
),
-- 步骤3获取每个中性面单号的首次成功时间和日期
NeutralWaybillSuccessInfo AS (
SELECT
s.NeutralWaybillNumber,
MIN(CASE WHEN s.Result = 0 THEN s.CreatedAt ELSE NULL END) AS ,
MIN(CASE WHEN s.Result = 0 THEN DATE(CONVERT_TZ(s.CreatedAt, '+00:00', '-05:00')) ELSE NULL END) AS
FROM label_scan_history s
GROUP BY s.NeutralWaybillNumber
),
-- 步骤4每日扫描数统计去重- 有客户简称
DailyScanCount AS (
SELECT
CustomerCode,
,
COUNT(DISTINCT NeutralWaybillNumber) AS
FROM (
-- 每个中性面单号每天取最新一条记录
SELECT
CustomerCode,
NeutralWaybillNumber,
,
ROW_NUMBER() OVER (PARTITION BY NeutralWaybillNumber, ORDER BY DESC) AS rn
FROM ScanWithCustomer
WHERE CustomerCode IS NOT NULL
) AS t
WHERE rn = 1
GROUP BY CustomerCode,
),
-- 步骤5每日换单成功数统计去重- 有客户简称去除STOP数
DailySuccessCount AS (
SELECT
CustomerCode,
,
COUNT(DISTINCT NeutralWaybillNumber) AS
FROM (
SELECT
CustomerCode,
NeutralWaybillNumber,
,
MAX(CASE WHEN Result = 0 THEN 1 ELSE 0 END) OVER (PARTITION BY NeutralWaybillNumber, ) AS has_success,
MAX(CASE WHEN Result = 0 AND Description LIKE '%STOP%' THEN 1 ELSE 0 END) OVER (PARTITION BY NeutralWaybillNumber, ) AS has_stop,
ROW_NUMBER() OVER (PARTITION BY NeutralWaybillNumber, ORDER BY DESC) AS rn
FROM ScanWithCustomer
WHERE CustomerCode IS NOT NULL
) AS t
WHERE rn = 1 AND has_success = 1 AND has_stop = 0
GROUP BY CustomerCode,
),
-- 步骤6每日换单失败数统计去重- 有客户简称,除去换单成功记录
DailyFailedCount AS (
SELECT
CustomerCode,
,
COUNT(DISTINCT NeutralWaybillNumber) AS
FROM (
SELECT
CustomerCode,
NeutralWaybillNumber,
,
MAX(CASE WHEN Result = 0 THEN 1 ELSE 0 END) OVER (PARTITION BY NeutralWaybillNumber, ) AS has_success,
MAX(CASE WHEN Result != 0 THEN 1 ELSE 0 END) OVER (PARTITION BY NeutralWaybillNumber, ) AS has_failure,
ROW_NUMBER() OVER (PARTITION BY NeutralWaybillNumber, ORDER BY DESC) AS rn
FROM ScanWithCustomer
WHERE CustomerCode IS NOT NULL
) AS t
WHERE rn = 1 AND has_success = 0
GROUP BY CustomerCode,
),
-- 步骤7每日STOP数统计去重- 有客户简称
DailyStopCount AS (
SELECT
CustomerCode,
,
COUNT(DISTINCT NeutralWaybillNumber) AS STOP数
FROM (
SELECT
CustomerCode,
NeutralWaybillNumber,
,
MAX(CASE WHEN Result = 0 AND Description LIKE '%STOP%' THEN 1 ELSE 0 END) OVER (PARTITION BY NeutralWaybillNumber, ) AS has_stop,
ROW_NUMBER() OVER (PARTITION BY NeutralWaybillNumber, ORDER BY DESC) AS rn
FROM ScanWithCustomer
WHERE CustomerCode IS NOT NULL
) AS t
WHERE rn = 1 AND has_stop = 1
GROUP BY CustomerCode,
),
-- 步骤8总无人认领数统计 - CustomerId为0的扫描记录去重
DailyUnclaimedCount AS (
SELECT
,
COUNT(DISTINCT NeutralWaybillNumber) AS
FROM (
SELECT
NeutralWaybillNumber,
,
ROW_NUMBER() OVER (PARTITION BY NeutralWaybillNumber, ORDER BY DESC) AS rn
FROM ScanWithCustomer
WHERE ScanCustomerId = 0
) AS t
WHERE rn = 1
GROUP BY
),
-- 步骤9总扫描次数统计不去重
DailyTotalScanCount AS (
SELECT
,
COUNT(*) AS
FROM ScanWithCustomer
GROUP BY
),
-- 步骤10收集所有日期
AllDates AS (
SELECT DISTINCT FROM DailyScanCount
UNION
SELECT DISTINCT FROM DailySuccessCount
UNION
SELECT DISTINCT FROM DailyFailedCount
UNION
SELECT DISTINCT FROM DailyStopCount
UNION
SELECT DISTINCT FROM DailyUnclaimedCount
UNION
SELECT DISTINCT FROM DailyTotalScanCount
),
-- 步骤11收集所有客户简称
AllCustomers AS (
SELECT DISTINCT CustomerCode FROM DailyScanCount
UNION
SELECT DISTINCT CustomerCode FROM DailySuccessCount
UNION
SELECT DISTINCT CustomerCode FROM DailyFailedCount
UNION
SELECT DISTINCT CustomerCode FROM DailyStopCount
)
-- 最终查询结果
SELECT
ad. AS ,
ac.CustomerCode AS ,
COALESCE(dsc., 0) AS ,
COALESCE(dsuc., 0) AS ,
COALESCE(dfac., 0) AS ,
COALESCE(dstc.STOP数, 0) AS STOP数,
-- 换单成功率
CASE
WHEN COALESCE(dsc., 0) = 0 THEN '0.00%'
ELSE CONCAT(ROUND(COALESCE(dsuc., 0) / COALESCE(dsc., 0) * 100, 2), '%')
END AS ,
COALESCE(duc., 0) AS ,
COALESCE(dtsc., 0) AS ,
(UTC_TIMESTAMP() - INTERVAL 5 HOUR) AS UTC_5
FROM AllDates ad
CROSS JOIN AllCustomers ac
LEFT JOIN DailyScanCount dsc ON ad. = dsc. AND ac.CustomerCode = dsc.CustomerCode
LEFT JOIN DailySuccessCount dsuc ON ad. = dsuc. AND ac.CustomerCode = dsuc.CustomerCode
LEFT JOIN DailyFailedCount dfac ON ad. = dfac. AND ac.CustomerCode = dfac.CustomerCode
LEFT JOIN DailyStopCount dstc ON ad. = dstc. AND ac.CustomerCode = dstc.CustomerCode
LEFT JOIN DailyUnclaimedCount duc ON ad. = duc.
LEFT JOIN DailyTotalScanCount dtsc ON ad. = dtsc.
WHERE COALESCE(dsc., 0) > 0
ORDER BY ad. DESC, ac.CustomerCode;