上传源代码版本
This commit is contained in:
347
最新运营监控.sql
Normal file
347
最新运营监控.sql
Normal file
@@ -0,0 +1,347 @@
|
||||
-- 每日标签统计综合查询(按需求重新设计)
|
||||
-- 设计逻辑:
|
||||
-- 1. 到货时间ReceiptTime本身是UTC-5,不需要转换
|
||||
-- 2. 其他时间(标签推送时间、扫描时间)是UTC-0,需要转换为UTC-5
|
||||
-- 3. 标签率计算:首次扫描前推送的标签数/交接单总订单数,无扫描记录则用当前标签数/总订单数
|
||||
-- 4. 考核时间仅针对标签率≥80%的有标签订单计算
|
||||
WITH
|
||||
-- 步骤1:获取所有到货交接单(时间已是UTC-5)
|
||||
ArrivalForms AS (
|
||||
SELECT
|
||||
Id AS FormId,
|
||||
HandoverNumber,
|
||||
ReceiptTime,
|
||||
DATE(ReceiptTime) AS ReceiptDate,
|
||||
HOUR(ReceiptTime) AS ReceiptHour
|
||||
FROM arrival_handover_forms
|
||||
),
|
||||
-- 步骤2:获取所有换单请求
|
||||
LabelRequests AS (
|
||||
SELECT
|
||||
Id AS RequestId,
|
||||
NeutralWaybillNumber,
|
||||
BillOfLadingNumber,
|
||||
MasterPackageNumber,
|
||||
Label,
|
||||
LabelRetrievedAt,
|
||||
CreatedAt AS RequestCreatedAt,
|
||||
-- 转换为UTC-5时间
|
||||
CASE WHEN LabelRetrievedAt IS NOT NULL THEN CONVERT_TZ(LabelRetrievedAt, '+00:00', '-05:00') END AS LabelRetrievedAt_UTC5,
|
||||
DATE(CONVERT_TZ(LabelRetrievedAt, '+00:00', '-05:00')) AS LabelRetrievedDate_UTC5
|
||||
FROM label_replace_requests
|
||||
),
|
||||
-- 步骤3:关联到货交接单和换单请求(优先匹配大箱号,无大箱号匹配则用提单号)
|
||||
FormRequestRelation AS (
|
||||
SELECT
|
||||
-- 优先取大箱号匹配的交接单信息,无则取提单号匹配的
|
||||
COALESCE(f_m.FormId, f_b.FormId) AS FormId,
|
||||
COALESCE(f_m.HandoverNumber, f_b.HandoverNumber) AS HandoverNumber,
|
||||
COALESCE(f_m.ReceiptTime, f_b.ReceiptTime) AS ReceiptTime,
|
||||
COALESCE(f_m.ReceiptDate, f_b.ReceiptDate) AS ReceiptDate,
|
||||
COALESCE(f_m.ReceiptHour, f_b.ReceiptHour) AS ReceiptHour,
|
||||
r.RequestId,
|
||||
r.NeutralWaybillNumber,
|
||||
r.Label,
|
||||
r.LabelRetrievedAt,
|
||||
r.LabelRetrievedAt_UTC5,
|
||||
r.LabelRetrievedDate_UTC5,
|
||||
r.RequestCreatedAt,
|
||||
-- 是否有标签
|
||||
CASE WHEN r.Label IS NOT NULL AND r.Label != '' THEN 1 ELSE 0 END AS HasLabel
|
||||
FROM LabelRequests r
|
||||
-- 先匹配大箱号
|
||||
LEFT JOIN ArrivalForms f_m ON r.MasterPackageNumber = f_m.HandoverNumber
|
||||
-- 大箱号匹配不到再匹配提单号
|
||||
LEFT JOIN ArrivalForms f_b ON r.BillOfLadingNumber = f_b.HandoverNumber
|
||||
-- 只保留有匹配到交接单的订单
|
||||
WHERE COALESCE(f_m.FormId, f_b.FormId) IS NOT NULL
|
||||
),
|
||||
-- 步骤4:获取每个交接单的首次扫描时间
|
||||
FormFirstScan AS (
|
||||
SELECT
|
||||
fr.FormId,
|
||||
MIN(s.CreatedAt) AS FirstScanTime,
|
||||
CONVERT_TZ(MIN(s.CreatedAt), '+00:00', '-05:00') AS FirstScanTime_UTC5
|
||||
FROM FormRequestRelation fr
|
||||
LEFT JOIN label_scan_history s ON fr.NeutralWaybillNumber = s.NeutralWaybillNumber
|
||||
GROUP BY fr.FormId
|
||||
),
|
||||
-- 步骤5:先计算每个交接单的总订单数和达标阈值
|
||||
FormTotalOrderCount AS (
|
||||
SELECT
|
||||
FormId,
|
||||
COUNT(DISTINCT RequestId) AS TotalOrderCount,
|
||||
CEIL(COUNT(DISTINCT RequestId) * 0.8) AS QualifyNeedCount
|
||||
FROM FormRequestRelation
|
||||
GROUP BY FormId
|
||||
),
|
||||
-- 步骤6:计算每个交接单每个标签的推送时间及排序,匹配达标阈值
|
||||
FormLabelPushTimes AS (
|
||||
SELECT
|
||||
fr.FormId,
|
||||
fr.LabelRetrievedAt_UTC5,
|
||||
-- 按推送时间排序,计算累计推送的标签数
|
||||
ROW_NUMBER() OVER (PARTITION BY fr.FormId ORDER BY fr.LabelRetrievedAt_UTC5) AS PushOrder,
|
||||
ftoc.QualifyNeedCount
|
||||
FROM FormRequestRelation fr
|
||||
INNER JOIN FormTotalOrderCount ftoc ON fr.FormId = ftoc.FormId
|
||||
WHERE fr.HasLabel = 1 AND fr.LabelRetrievedAt_UTC5 IS NOT NULL
|
||||
),
|
||||
-- 步骤7:计算每个交接单的首次达标日期和时间
|
||||
FormFirstQualifiedDate AS (
|
||||
SELECT
|
||||
FormId,
|
||||
MIN(DATE(LabelRetrievedAt_UTC5)) AS FirstQualifiedDate,
|
||||
MIN(LabelRetrievedAt_UTC5) AS FirstQualifiedTime_UTC5
|
||||
FROM FormLabelPushTimes
|
||||
WHERE PushOrder >= QualifyNeedCount
|
||||
GROUP BY FormId
|
||||
),
|
||||
-- 步骤8:计算每个交接单的标签率(按当前实际情况统计,无需冻结)
|
||||
FormLabelRateAndQualifiedDate AS (
|
||||
SELECT
|
||||
fr.FormId,
|
||||
ftoc.TotalOrderCount,
|
||||
-- 有标签的订单数
|
||||
COUNT(DISTINCT CASE WHEN fr.HasLabel = 1 THEN fr.RequestId END) AS HasLabelOrderCount,
|
||||
-- 标签率:当前有标签订单数 / 总订单数
|
||||
CASE
|
||||
WHEN ftoc.TotalOrderCount = 0 THEN 0
|
||||
ELSE COUNT(DISTINCT CASE WHEN fr.HasLabel = 1 THEN fr.RequestId END) / ftoc.TotalOrderCount
|
||||
END AS LabelRate,
|
||||
fqd.FirstQualifiedDate,
|
||||
fqd.FirstQualifiedTime_UTC5
|
||||
FROM FormRequestRelation fr
|
||||
INNER JOIN FormTotalOrderCount ftoc ON fr.FormId = ftoc.FormId
|
||||
LEFT JOIN FormFirstQualifiedDate fqd ON fr.FormId = fqd.FormId
|
||||
GROUP BY fr.FormId, ftoc.TotalOrderCount, fqd.FirstQualifiedDate, fqd.FirstQualifiedTime_UTC5
|
||||
),
|
||||
-- 步骤9:计算每个订单的考核时间(基于达标时间和到货时间较晚者)
|
||||
OrderAssessment AS (
|
||||
SELECT
|
||||
fr.*,
|
||||
flr.LabelRate,
|
||||
flr.FirstQualifiedDate,
|
||||
flr.FirstQualifiedTime_UTC5,
|
||||
fs.FirstScanTime_UTC5,
|
||||
-- 订单创建日期(UTC-5)
|
||||
DATE(CONVERT_TZ(fr.RequestCreatedAt, '+00:00', '-05:00')) AS RequestCreatedDate_UTC5,
|
||||
-- 考核基准时间:如果首次扫描早于到仓则用首次扫描时间,再和标签率达标时间取较晚者
|
||||
GREATEST(
|
||||
CASE
|
||||
WHEN fs.FirstScanTime_UTC5 IS NOT NULL AND fs.FirstScanTime_UTC5 < fr.ReceiptTime
|
||||
THEN fs.FirstScanTime_UTC5
|
||||
ELSE fr.ReceiptTime
|
||||
END,
|
||||
flr.FirstQualifiedTime_UTC5
|
||||
) AS AssessmentBaseTime,
|
||||
-- 考核时间计算(仅标签率≥80%且有标签的订单)
|
||||
CASE
|
||||
WHEN flr.FirstQualifiedTime_UTC5 IS NOT NULL AND fr.HasLabel = 1 THEN
|
||||
CASE
|
||||
-- 考核基准时间16点前:考核截止次日16点
|
||||
WHEN HOUR(GREATEST(
|
||||
CASE
|
||||
WHEN fs.FirstScanTime_UTC5 IS NOT NULL AND fs.FirstScanTime_UTC5 < fr.ReceiptTime
|
||||
THEN fs.FirstScanTime_UTC5
|
||||
ELSE fr.ReceiptTime
|
||||
END,
|
||||
flr.FirstQualifiedTime_UTC5
|
||||
)) < 16 THEN
|
||||
DATE_ADD(
|
||||
DATE_ADD(DATE(GREATEST(
|
||||
CASE
|
||||
WHEN fs.FirstScanTime_UTC5 IS NOT NULL AND fs.FirstScanTime_UTC5 < fr.ReceiptTime
|
||||
THEN fs.FirstScanTime_UTC5
|
||||
ELSE fr.ReceiptTime
|
||||
END,
|
||||
flr.FirstQualifiedTime_UTC5
|
||||
)), INTERVAL 1 DAY),
|
||||
INTERVAL 16 HOUR
|
||||
)
|
||||
-- 考核基准时间16点后:考核截止次日23:59:59
|
||||
ELSE
|
||||
DATE_ADD(
|
||||
DATE_ADD(DATE(GREATEST(
|
||||
CASE
|
||||
WHEN fs.FirstScanTime_UTC5 IS NOT NULL AND fs.FirstScanTime_UTC5 < fr.ReceiptTime
|
||||
THEN fs.FirstScanTime_UTC5
|
||||
ELSE fr.ReceiptTime
|
||||
END,
|
||||
flr.FirstQualifiedTime_UTC5
|
||||
)), INTERVAL 1 DAY),
|
||||
INTERVAL '23:59:59' HOUR_SECOND
|
||||
)
|
||||
END
|
||||
ELSE NULL
|
||||
END AS AssessmentTime
|
||||
FROM FormRequestRelation fr
|
||||
LEFT JOIN FormLabelRateAndQualifiedDate flr ON fr.FormId = flr.FormId
|
||||
LEFT JOIN FormFirstScan fs ON fr.FormId = fs.FormId
|
||||
WHERE fr.HasLabel = 1 -- 仅统计有标签的订单
|
||||
),
|
||||
-- 步骤7:获取每个订单的扫描状态
|
||||
OrderScanStatus AS (
|
||||
SELECT
|
||||
s.NeutralWaybillNumber,
|
||||
-- 首次成功时间(UTC-5)
|
||||
MIN(CASE WHEN s.Result = 0 THEN CONVERT_TZ(s.CreatedAt, '+00:00', '-05:00') END) AS FirstSuccessTime_UTC5,
|
||||
DATE(MIN(CASE WHEN s.Result = 0 THEN CONVERT_TZ(s.CreatedAt, '+00:00', '-05:00') END)) AS FirstSuccessDate_UTC5,
|
||||
-- 是否成功
|
||||
MAX(CASE WHEN s.Result = 0 THEN 1 ELSE 0 END) AS IsSuccess,
|
||||
-- 是否是STOP标签
|
||||
MAX(CASE WHEN s.Result = 0 AND s.Description LIKE '%成功返回STOP标签%' THEN 1 ELSE 0 END) AS IsStopLabel
|
||||
FROM label_scan_history s
|
||||
GROUP BY s.NeutralWaybillNumber
|
||||
),
|
||||
-- 步骤8:合并订单信息和扫描状态
|
||||
OrderFullInfo AS (
|
||||
SELECT
|
||||
oa.*,
|
||||
oss.FirstSuccessTime_UTC5,
|
||||
oss.FirstSuccessDate_UTC5,
|
||||
oss.IsSuccess,
|
||||
oss.IsStopLabel,
|
||||
-- 是否在考核时间内完成
|
||||
CASE
|
||||
WHEN oa.AssessmentTime IS NOT NULL AND oss.IsSuccess = 1
|
||||
AND oss.FirstSuccessTime_UTC5 <= oa.AssessmentTime
|
||||
THEN 1 ELSE 0
|
||||
END AS IsCompletedInAssessment
|
||||
FROM OrderAssessment oa
|
||||
LEFT JOIN OrderScanStatus oss ON oa.NeutralWaybillNumber = oss.NeutralWaybillNumber
|
||||
),
|
||||
-- 步骤9:独立统计每日扫描次数(不关联其他表,统计所有扫描记录)
|
||||
DailyScanCount AS (
|
||||
SELECT
|
||||
DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00')) AS 日期,
|
||||
COUNT(*) AS 当日扫描数
|
||||
FROM label_scan_history
|
||||
GROUP BY DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00'))
|
||||
),
|
||||
-- 步骤10:独立统计每日成功换单的去重订单数(不关联其他表)
|
||||
DailySuccessCount AS (
|
||||
SELECT
|
||||
DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00')) AS 日期,
|
||||
COUNT(DISTINCT NeutralWaybillNumber) AS 当日换单完成数
|
||||
FROM label_scan_history
|
||||
WHERE Result = 0
|
||||
GROUP BY DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00'))
|
||||
),
|
||||
-- 步骤11:独立统计每日失败换单的去重订单数(当日有失败且无成功,不限制是否有标签)
|
||||
DailyFailCount AS (
|
||||
SELECT
|
||||
日期,
|
||||
COUNT(DISTINCT NeutralWaybillNumber) AS 当日换单失败数
|
||||
FROM (
|
||||
SELECT
|
||||
DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00')) AS 日期,
|
||||
NeutralWaybillNumber,
|
||||
MAX(CASE WHEN Result = 0 THEN 1 ELSE 0 END) AS has_success,
|
||||
MAX(CASE WHEN Result != 0 THEN 1 ELSE 0 END) AS has_fail
|
||||
FROM label_scan_history
|
||||
GROUP BY DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00')), NeutralWaybillNumber
|
||||
) t
|
||||
WHERE has_fail = 1 AND has_success = 0
|
||||
GROUP BY 日期
|
||||
),
|
||||
-- 步骤12:独立统计每日STOP标签的去重订单数
|
||||
DailyStopCount AS (
|
||||
SELECT
|
||||
DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00')) AS 日期,
|
||||
COUNT(DISTINCT NeutralWaybillNumber) AS 当日STOP数
|
||||
FROM label_scan_history
|
||||
WHERE Result = 0 AND Description LIKE '%成功返回STOP标签%'
|
||||
GROUP BY DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00'))
|
||||
),
|
||||
-- 步骤10:获取所有日期维度
|
||||
AllDates AS (
|
||||
SELECT ReceiptDate AS 日期 FROM OrderFullInfo -- 到仓日期(UTC-5)
|
||||
UNION
|
||||
SELECT LabelRetrievedDate_UTC5 AS 日期 FROM OrderFullInfo WHERE LabelRetrievedDate_UTC5 IS NOT NULL -- 标签推送日期(UTC-5)
|
||||
UNION
|
||||
SELECT FirstSuccessDate_UTC5 AS 日期 FROM OrderFullInfo WHERE FirstSuccessDate_UTC5 IS NOT NULL -- 换单成功日期(UTC-5)
|
||||
UNION
|
||||
SELECT DATE(AssessmentBaseTime) AS 日期 FROM OrderFullInfo WHERE AssessmentBaseTime IS NOT NULL -- 考核基准日期(UTC-5)
|
||||
UNION
|
||||
SELECT DATE(AssessmentTime) AS 日期 FROM OrderFullInfo WHERE AssessmentTime IS NOT NULL -- 考核截止日期(UTC-5)
|
||||
UNION
|
||||
SELECT DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00')) AS 日期 FROM label_scan_history WHERE CreatedAt IS NOT NULL -- 扫描日期(转UTC-5)
|
||||
UNION
|
||||
SELECT DATE(CONVERT_TZ(LabelRetrievedAt, '+00:00', '-05:00')) AS 日期 FROM label_replace_requests WHERE LabelRetrievedAt IS NOT NULL -- 标签推送日期(转UTC-5)
|
||||
UNION
|
||||
SELECT DATE(CONVERT_TZ(CreatedAt, '+00:00', '-05:00')) AS 日期 FROM label_scan_history WHERE Result = 0 AND CreatedAt IS NOT NULL -- 换单完成日期(转UTC-5)
|
||||
UNION
|
||||
SELECT 日期 FROM DailyScanCount
|
||||
),
|
||||
-- 步骤10:去重排序日期
|
||||
DistinctDates AS (
|
||||
SELECT DISTINCT 日期
|
||||
FROM AllDates
|
||||
ORDER BY 日期
|
||||
),
|
||||
-- 步骤11:每日指标汇总
|
||||
DailyMetrics AS (
|
||||
SELECT
|
||||
dd.日期,
|
||||
-- 当天新增换单数:到仓时间是当天的有标签订单数
|
||||
COUNT(DISTINCT CASE WHEN ofi.ReceiptDate = dd.日期 THEN ofi.RequestId END) AS 当天新增换单数,
|
||||
-- 当天应该换单数:有考核时间、考核基准日期是当天或考核截止日期是当天,且换单完成时间小于等于统计日期的订单(有考核时间默认标签率≥80%)
|
||||
COUNT(DISTINCT CASE
|
||||
WHEN ofi.AssessmentTime IS NOT NULL
|
||||
AND (DATE(ofi.AssessmentBaseTime) = dd.日期 OR DATE(ofi.AssessmentTime) = dd.日期)
|
||||
AND (ofi.IsSuccess = 0 OR ofi.FirstSuccessDate_UTC5 <= dd.日期)
|
||||
THEN ofi.RequestId
|
||||
END) AS 当天应该换单数,
|
||||
-- 当日标签推送数:标签推送时间是当天的订单数
|
||||
COUNT(DISTINCT CASE WHEN ofi.LabelRetrievedDate_UTC5 = dd.日期 THEN ofi.RequestId END) AS 当日标签推送数,
|
||||
-- 累计要换的总单数:有标签,标签推送时间<=统计日期,创建时间<=统计日期,且统计日当天未完成换单的不重复订单总数(不考虑标签率、到仓时间、考核时间)
|
||||
COUNT(DISTINCT CASE
|
||||
WHEN ofi.HasLabel = 1
|
||||
AND ofi.LabelRetrievedDate_UTC5 <= dd.日期
|
||||
AND ofi.RequestCreatedDate_UTC5 <= dd.日期
|
||||
AND (ofi.IsSuccess = 0 OR ofi.FirstSuccessDate_UTC5 > dd.日期)
|
||||
THEN ofi.RequestId
|
||||
END) AS 累计要换的总单数,
|
||||
-- 24小时换单成功数:当天应该换单数中、首次成功时间在考核基准时间与考核时间之间、且完成时间是当天的订单数
|
||||
COUNT(DISTINCT CASE
|
||||
WHEN ofi.AssessmentTime IS NOT NULL
|
||||
AND (DATE(ofi.AssessmentBaseTime) = dd.日期 OR DATE(ofi.AssessmentTime) = dd.日期)
|
||||
AND ofi.IsCompletedInAssessment = 1
|
||||
AND ofi.FirstSuccessDate_UTC5 = dd.日期
|
||||
THEN ofi.RequestId
|
||||
END) AS 24H完成数
|
||||
FROM DistinctDates dd
|
||||
CROSS JOIN OrderFullInfo ofi
|
||||
GROUP BY dd.日期
|
||||
)
|
||||
-- 最终输出
|
||||
SELECT
|
||||
dm.日期,
|
||||
dm.当天新增换单数,
|
||||
dm.累计要换的总单数,
|
||||
dm.当天应该换单数,
|
||||
COALESCE(dsucc.当日换单完成数, 0) AS 当日换单完成数,
|
||||
COALESCE(dfail.当日换单失败数, 0) AS 当日换单失败数,
|
||||
COALESCE(dstop.当日STOP数, 0) AS 当日STOP数,
|
||||
dm.24H完成数 AS 24小时换单成功数,
|
||||
dm.当日标签推送数,
|
||||
COALESCE(dsc.当日扫描数, 0) AS 当日扫描数,
|
||||
-- 当天换单完成率:当日换单完成数 / 当天应该换单数
|
||||
CASE
|
||||
WHEN dm.当天应该换单数 = 0 THEN '0.00%'
|
||||
ELSE CONCAT(ROUND(COALESCE(dsucc.当日换单完成数, 0) / dm.当天应该换单数 * 100, 2), '%')
|
||||
END AS 当天换单完成率,
|
||||
-- 24小时换单率:考核时间内完成数 / 当天应该考核的订单总数
|
||||
CASE
|
||||
WHEN dm.当天应该换单数 = 0 THEN '0.00%'
|
||||
ELSE CONCAT(ROUND(dm.24H完成数 / dm.当天应该换单数 * 100, 2), '%')
|
||||
END AS 24小时换单率,
|
||||
-- 数据拉取时间
|
||||
(UTC_TIMESTAMP() - INTERVAL 5 HOUR) AS 数据拉取时间(UTC_5)
|
||||
FROM DailyMetrics dm
|
||||
LEFT JOIN DailyScanCount dsc ON dm.日期 = dsc.日期
|
||||
LEFT JOIN DailySuccessCount dsucc ON dm.日期 = dsucc.日期
|
||||
LEFT JOIN DailyFailCount dfail ON dm.日期 = dfail.日期
|
||||
LEFT JOIN DailyStopCount dstop ON dm.日期 = dstop.日期
|
||||
ORDER BY dm.日期 DESC;
|
||||
Reference in New Issue
Block a user