Files
LabelChange-server/customer-daily-stats.sql
2026-06-01 16:30:29 +08:00

201 lines
7.2 KiB
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.

-- 客户维度每日标签统计查询(不关联订单表)
-- 设计逻辑:
-- 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;