고객 추이 정합성 역산
This commit is contained in:
parent
e593be0a2d
commit
fcbab196cb
|
|
@ -30,29 +30,36 @@ public interface CustomerRepository extends JpaRepository<Customer, Long> {
|
|||
// 오늘 추가된 고객 수: cus_contract_date = 오늘
|
||||
long countByCusContractDate(LocalDate cusContractDate);
|
||||
|
||||
// 날짜별 활성 고객 수 + 신규/해지 (선그래프·막대그래프용).
|
||||
// - active_count = cus_status='A' 이고 그 날짜에 계약기간 안에 있던 고객 수 (날짜로 과거 재구성)
|
||||
// - added_count = 그 날짜에 계약 시작 (cus_contract_date = D)
|
||||
// - removed_count = 그 날짜에 해지 (cus_terminated_date = D)
|
||||
// - generate_series 로 [startDate, endDate] 각 날짜 생성 → 빈 날도 0
|
||||
// 날짜별 활성 곳 수 + 일별 신규/해지 — "현재 기준 역산(reverse-calc)" 모델.
|
||||
// - 기준점: 오늘 활성 = cus_status='A' 수 (신뢰 기준, 카드와 동일)
|
||||
// - 과거 D의 활성 = 오늘 활성 − (D 이후 신규 계약) + (D 이후 해지)
|
||||
// · D 이후 신규는 D 시점엔 아직 없었으니 빼고
|
||||
// · D 이후 해지는 D 시점엔 아직 있었으니 더함
|
||||
// - added/removed 는 effective date(cus_contract_date / cus_terminated_date) 기준 일별 이벤트
|
||||
// - active(D) = active(D-1) + added(D) − removed(D) 가 정확히 성립.
|
||||
// 소급(백데이트)된 건도 매 조회마다 현재 날짜값으로 재계산되어 effective date 위치에 반영됨.
|
||||
// - return: [0]=날짜(date), [1]=active(bigint), [2]=added(bigint), [3]=removed(bigint)
|
||||
@Query(value = """
|
||||
SELECT CAST(series.day AS date) AS day,
|
||||
(SELECT COUNT(*) FROM crm.customer c
|
||||
WHERE c.cus_status = 'A'
|
||||
AND c.cus_contract_date <= CAST(series.day AS date)
|
||||
AND (c.cus_terminated_date IS NULL OR c.cus_terminated_date > CAST(series.day AS date))
|
||||
SELECT days.day AS day,
|
||||
( (SELECT COUNT(*) FROM crm.customer WHERE cus_status = 'A')
|
||||
- (SELECT COUNT(*) FROM crm.customer
|
||||
WHERE cus_contract_date > days.day
|
||||
AND cus_contract_date <= CAST(:endDate AS date))
|
||||
+ (SELECT COUNT(*) FROM crm.customer
|
||||
WHERE cus_terminated_date > days.day
|
||||
AND cus_terminated_date <= CAST(:endDate AS date))
|
||||
) AS active_count,
|
||||
(SELECT COUNT(*) FROM crm.customer a
|
||||
WHERE a.cus_contract_date = CAST(series.day AS date)
|
||||
) AS added_count,
|
||||
(SELECT COUNT(*) FROM crm.customer r
|
||||
WHERE r.cus_terminated_date = CAST(series.day AS date)
|
||||
) AS removed_count
|
||||
FROM generate_series(CAST(:startDate AS timestamp),
|
||||
CAST(:endDate AS timestamp),
|
||||
INTERVAL '1 day') AS series(day)
|
||||
ORDER BY series.day
|
||||
(SELECT COUNT(*) FROM crm.customer
|
||||
WHERE cus_contract_date = days.day) AS added_count,
|
||||
(SELECT COUNT(*) FROM crm.customer
|
||||
WHERE cus_terminated_date = days.day) AS removed_count
|
||||
FROM (
|
||||
SELECT CAST(series.day AS date) AS day
|
||||
FROM generate_series(CAST(:startDate AS timestamp),
|
||||
CAST(:endDate AS timestamp),
|
||||
INTERVAL '1 day') AS series(day)
|
||||
) days
|
||||
ORDER BY days.day
|
||||
""", nativeQuery = true)
|
||||
List<Object[]> findActiveCustomerTrend(@Param("startDate") LocalDate startDate,
|
||||
@Param("endDate") LocalDate endDate);
|
||||
|
|
|
|||
Loading…
Reference in New Issue