add totalNumberValue for rank

This commit is contained in:
Timi
2026-08-14 18:58:04 +08:00
parent ab4a164680
commit 457e716b38
4 changed files with 174 additions and 130 deletions
@@ -160,6 +160,9 @@
#{eventId}
</foreach>
</if>
<if test="rankType != null and rankType.name() == 'TOTAL_NUMBER_VALUE'">
AND r.`number_value` IS NOT NULL
</if>
</sql>
<select id="countRankByRange" resultType="long">
SELECT
@@ -170,134 +173,154 @@
<include refid="rankWhere"/>
</select>
<select id="selectRankByRange" resultType="com.imyeyu.api.modules.gao.vo.GaoCustomerEventRankView">
WITH RECURSIVE `daily_stat` AS (
SELECT
r.`customer_id` AS `customerId`,
r.`registered_date_value` AS `registeredDateValue`,
COUNT(1) AS `dailyCount`,
MAX(r.`registered_at`) AS `latestRegisteredAt`
FROM `gao_event_record` r
LEFT JOIN `gao_customer` c ON r.`customer_id` = c.`id`
WHERE
<include refid="rankWhere"/>
GROUP BY
r.`customer_id`,
r.`registered_date_value`
),
`range_bound` AS (
SELECT
LEAST(
STR_TO_DATE(CAST(MIN(`registeredDateValue`) AS CHAR), '%Y%m%d'),
STR_TO_DATE(CAST(#{todayDateValue} AS CHAR), '%Y%m%d')
) AS `beginDate`,
STR_TO_DATE(CAST(#{todayDateValue} AS CHAR), '%Y%m%d') AS `endDate`
FROM `daily_stat`
),
`calendar` AS (
SELECT
CAST(DATE_FORMAT(`beginDate`, '%Y%m%d') AS UNSIGNED) AS `dateValue`,
`beginDate` AS `dateDate`
FROM `range_bound`
WHERE `beginDate` IS NOT NULL
UNION ALL
SELECT
CAST(DATE_FORMAT(DATE_ADD(c.`dateDate`, INTERVAL 1 DAY), '%Y%m%d') AS UNSIGNED) AS `dateValue`,
DATE_ADD(c.`dateDate`, INTERVAL 1 DAY) AS `dateDate`
FROM `calendar` c
JOIN `range_bound` b ON c.`dateDate` &lt; b.`endDate`
),
`open_calendar` AS (
SELECT
c.`dateValue`,
ROW_NUMBER() OVER (ORDER BY c.`dateDate`) AS `openIndex`
FROM `calendar` c
LEFT JOIN `gao_store_business_day` b ON b.`store_id` = #{storeId}
AND b.`date_value` = c.`dateValue`
AND b.`deleted_at` IS NULL
WHERE COALESCE(b.`status`, 'OPEN') != 'CLOSED'
),
`rank_stat` AS (
SELECT
`customerId`,
COUNT(1) AS `totalEventDays`,
SUM(`dailyCount`) AS `totalEventCount`,
MAX(`latestRegisteredAt`) AS `latestRegisteredAt`
FROM `daily_stat`
GROUP BY `customerId`
),
`continuous_ordered` AS (
SELECT
d.`customerId`,
o.`openIndex`,
ROW_NUMBER() OVER (PARTITION BY d.`customerId` ORDER BY o.`openIndex` DESC) AS `dayIndex`
FROM `daily_stat` d
JOIN `open_calendar` o ON d.`registeredDateValue` = o.`dateValue`
),
`anchor_date` AS (
SELECT
MAX(`openIndex`) AS `anchorOpenIndex`
FROM `open_calendar`
),
`continuous_stat` AS (
SELECT
o.`customerId`,
CASE
WHEN COUNT(1) &lt; 2 THEN 0
ELSE COUNT(1)
END AS `recentContinuousEventDays`
FROM `continuous_ordered` o
JOIN `anchor_date` a
WHERE
o.`openIndex` + o.`dayIndex` = a.`anchorOpenIndex` + 1
<if test="eventIdList == null or eventIdList.size() != 1">
AND 1 = 0
</if>
GROUP BY o.`customerId`
),
`ranked` AS (
SELECT
ROW_NUMBER() OVER (
ORDER BY
<choose>
<when test="rankType != null and rankType.name() == 'TOTAL_COUNT'">
r.`totalEventCount` DESC,
r.`totalEventDays` DESC,
r.`latestRegisteredAt` DESC,
r.`customerId`
</when>
<when test="rankType != null and rankType.name() == 'CONTINUOUS_DAYS'">
COALESCE(c.`recentContinuousEventDays`, 0) DESC,
r.`totalEventDays` DESC,
r.`totalEventCount` DESC,
r.`latestRegisteredAt` DESC,
r.`customerId`
</when>
<otherwise>
r.`totalEventDays` DESC,
r.`totalEventCount` DESC,
r.`latestRegisteredAt` DESC,
r.`customerId`
</otherwise>
</choose>
) AS `rank`,
r.`customerId`,
r.`totalEventDays`,
r.`totalEventCount`,
COALESCE(c.`recentContinuousEventDays`, 0) AS `recentContinuousEventDays`,
r.`latestRegisteredAt`
FROM `rank_stat` r
LEFT JOIN `continuous_stat` c ON r.`customerId` = c.`customerId`
)
SELECT
`rank`,
`customerId`,
`totalEventDays`,
`totalEventCount`,
`recentContinuousEventDays`,
`latestRegisteredAt`
FROM `ranked`
ORDER BY `rank`
LIMIT #{offset}, #{limit}
<choose>
<when test="rankType == null or rankType.name() == 'TOTAL_DAYS'">
SELECT
ROW_NUMBER() OVER (
ORDER BY COUNT(DISTINCT r.`registered_date_value`) DESC, r.`customer_id`
) AS `rank`,
r.`customer_id` AS `customerId`,
COUNT(DISTINCT r.`registered_date_value`) AS `totalEventDays`,
NULL AS `totalEventCount`,
NULL AS `recentContinuousEventDays`,
NULL AS `totalNumberValue`,
NULL AS `latestRegisteredAt`
FROM `gao_event_record` r
LEFT JOIN `gao_customer` c ON r.`customer_id` = c.`id`
WHERE
<include refid="rankWhere"/>
GROUP BY r.`customer_id`
ORDER BY `rank`
LIMIT #{offset}, #{limit}
</when>
<when test="rankType.name() == 'TOTAL_COUNT'">
SELECT
ROW_NUMBER() OVER (
ORDER BY COUNT(1) DESC, r.`customer_id`
) AS `rank`,
r.`customer_id` AS `customerId`,
NULL AS `totalEventDays`,
COUNT(1) AS `totalEventCount`,
NULL AS `recentContinuousEventDays`,
NULL AS `totalNumberValue`,
NULL AS `latestRegisteredAt`
FROM `gao_event_record` r
LEFT JOIN `gao_customer` c ON r.`customer_id` = c.`id`
WHERE
<include refid="rankWhere"/>
GROUP BY r.`customer_id`
ORDER BY `rank`
LIMIT #{offset}, #{limit}
</when>
<when test="rankType.name() == 'TOTAL_NUMBER_VALUE'">
SELECT
ROW_NUMBER() OVER (
ORDER BY SUM(r.`number_value`) DESC, r.`customer_id`
) AS `rank`,
r.`customer_id` AS `customerId`,
NULL AS `totalEventDays`,
NULL AS `totalEventCount`,
NULL AS `recentContinuousEventDays`,
SUM(r.`number_value`) AS `totalNumberValue`,
NULL AS `latestRegisteredAt`
FROM `gao_event_record` r
LEFT JOIN `gao_customer` c ON r.`customer_id` = c.`id`
WHERE
<include refid="rankWhere"/>
GROUP BY r.`customer_id`
ORDER BY `rank`
LIMIT #{offset}, #{limit}
</when>
<otherwise>
WITH RECURSIVE `daily_stat` AS (
SELECT
r.`customer_id` AS `customerId`,
r.`registered_date_value` AS `registeredDateValue`
FROM `gao_event_record` r
LEFT JOIN `gao_customer` c ON r.`customer_id` = c.`id`
WHERE
<include refid="rankWhere"/>
GROUP BY
r.`customer_id`,
r.`registered_date_value`
),
`range_bound` AS (
SELECT
LEAST(
STR_TO_DATE(CAST(MIN(`registeredDateValue`) AS CHAR), '%Y%m%d'),
STR_TO_DATE(CAST(#{todayDateValue} AS CHAR), '%Y%m%d')
) AS `beginDate`,
STR_TO_DATE(CAST(#{todayDateValue} AS CHAR), '%Y%m%d') AS `endDate`
FROM `daily_stat`
),
`calendar` AS (
SELECT
CAST(DATE_FORMAT(`beginDate`, '%Y%m%d') AS UNSIGNED) AS `dateValue`,
`beginDate` AS `dateDate`
FROM `range_bound`
WHERE `beginDate` IS NOT NULL
UNION ALL
SELECT
CAST(DATE_FORMAT(DATE_ADD(c.`dateDate`, INTERVAL 1 DAY), '%Y%m%d') AS UNSIGNED) AS `dateValue`,
DATE_ADD(c.`dateDate`, INTERVAL 1 DAY) AS `dateDate`
FROM `calendar` c
JOIN `range_bound` b ON c.`dateDate` &lt; b.`endDate`
),
`open_calendar` AS (
SELECT
c.`dateValue`,
ROW_NUMBER() OVER (ORDER BY c.`dateDate`) AS `openIndex`
FROM `calendar` c
LEFT JOIN `gao_store_business_day` b ON b.`store_id` = #{storeId}
AND b.`date_value` = c.`dateValue`
AND b.`deleted_at` IS NULL
WHERE COALESCE(b.`status`, 'OPEN') != 'CLOSED'
),
`continuous_ordered` AS (
SELECT
d.`customerId`,
o.`openIndex`,
ROW_NUMBER() OVER (PARTITION BY d.`customerId` ORDER BY o.`openIndex` DESC) AS `dayIndex`
FROM `daily_stat` d
JOIN `open_calendar` o ON d.`registeredDateValue` = o.`dateValue`
),
`anchor_date` AS (
SELECT
MAX(`openIndex`) AS `anchorOpenIndex`
FROM `open_calendar`
),
`continuous_stat` AS (
SELECT
o.`customerId`,
CASE
WHEN COUNT(1) &lt; 2 THEN 0
ELSE COUNT(1)
END AS `recentContinuousEventDays`
FROM `continuous_ordered` o
JOIN `anchor_date` a
WHERE
o.`openIndex` + o.`dayIndex` = a.`anchorOpenIndex` + 1
<if test="eventIdList == null or eventIdList.size() != 1">
AND 1 = 0
</if>
GROUP BY o.`customerId`
)
SELECT
ROW_NUMBER() OVER (
ORDER BY COALESCE(c.`recentContinuousEventDays`, 0) DESC, r.`customerId`
) AS `rank`,
r.`customerId`,
NULL AS `totalEventDays`,
NULL AS `totalEventCount`,
COALESCE(c.`recentContinuousEventDays`, 0) AS `recentContinuousEventDays`,
NULL AS `totalNumberValue`,
NULL AS `latestRegisteredAt`
FROM (SELECT DISTINCT `customerId` FROM `daily_stat`) r
LEFT JOIN `continuous_stat` c ON r.`customerId` = c.`customerId`
ORDER BY `rank`
LIMIT #{offset}, #{limit}
</otherwise>
</choose>
</select>
<sql id="storeChartRangeWhere">