上传源代码版本
This commit is contained in:
201
customer-daily-stats.sql
Normal file
201
customer-daily-stats.sql
Normal 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;
|
||||
Reference in New Issue
Block a user