고객 수 추이에 +- 추가
This commit is contained in:
parent
0b2e744a0f
commit
4110a9f2f1
|
|
@ -19,6 +19,12 @@ public class CustomerActiveTrendPointDto {
|
||||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
|
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
|
||||||
private LocalDate date;
|
private LocalDate date;
|
||||||
|
|
||||||
// 그 날짜에 활성( cus_contract_date <= date AND (terminated IS NULL OR terminated > date) )인 고객 수
|
// 그 날짜의 활성 고객 수 (cus_status='A' 기준, 날짜로 과거 재구성)
|
||||||
private long count;
|
private long count;
|
||||||
|
|
||||||
|
// 그 날짜에 계약 시작한 고객 수 (cus_contract_date = date)
|
||||||
|
private long added;
|
||||||
|
|
||||||
|
// 그 날짜에 해지된 고객 수 (cus_terminated_date = date)
|
||||||
|
private long removed;
|
||||||
}
|
}
|
||||||
|
|
@ -30,24 +30,29 @@ public interface CustomerRepository extends JpaRepository<Customer, Long> {
|
||||||
// 오늘 추가된 고객 수: cus_contract_date = 오늘
|
// 오늘 추가된 고객 수: cus_contract_date = 오늘
|
||||||
long countByCusContractDate(LocalDate cusContractDate);
|
long countByCusContractDate(LocalDate cusContractDate);
|
||||||
|
|
||||||
// 날짜별 활성 고객 수 (선그래프용).
|
// 날짜별 활성 고객 수 + 신규/해지 (선그래프·막대그래프용).
|
||||||
// - 활성 기준 = cus_status='A' (현재 활성 플래그가 진짜 기준)
|
// - active_count = cus_status='A' 이고 그 날짜에 계약기간 안에 있던 고객 수 (날짜로 과거 재구성)
|
||||||
// - 그 위에 날짜로 과거 시점 재구성: cus_contract_date <= D AND (cus_terminated_date IS NULL OR cus_terminated_date > D)
|
// - added_count = 그 날짜에 계약 시작 (cus_contract_date = D)
|
||||||
// - 즉 "지금 활성('A')이면서 그 날짜에 계약기간 안에 있던" 고객 수 → 오늘 값은 전체(활성) 고객 수와 일치
|
// - removed_count = 그 날짜에 해지 (cus_terminated_date = D)
|
||||||
// - generate_series 로 [startDate, endDate] 각 날짜를 만들고 LEFT JOIN 으로 카운트 → 빈 날도 0으로 채워짐
|
// - generate_series 로 [startDate, endDate] 각 날짜 생성 → 빈 날도 0
|
||||||
// - return: [0]=날짜(date), [1]=활성 고객 수(bigint)
|
// - return: [0]=날짜(date), [1]=active(bigint), [2]=added(bigint), [3]=removed(bigint)
|
||||||
@Query(value = """
|
@Query(value = """
|
||||||
SELECT CAST(series.day AS date) AS day,
|
SELECT CAST(series.day AS date) AS day,
|
||||||
COUNT(c.cus_id) AS active_count
|
(SELECT COUNT(*) FROM crm.customer c
|
||||||
FROM generate_series(CAST(:startDate AS timestamp),
|
WHERE c.cus_status = 'A'
|
||||||
CAST(:endDate AS timestamp),
|
|
||||||
INTERVAL '1 day') AS series(day)
|
|
||||||
LEFT JOIN crm.customer c
|
|
||||||
ON c.cus_status = 'A'
|
|
||||||
AND c.cus_contract_date IS NOT NULL
|
AND c.cus_contract_date IS NOT NULL
|
||||||
AND c.cus_contract_date <= CAST(series.day AS date)
|
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))
|
AND (c.cus_terminated_date IS NULL OR c.cus_terminated_date > CAST(series.day AS date))
|
||||||
GROUP BY series.day
|
) 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
|
ORDER BY series.day
|
||||||
""", nativeQuery = true)
|
""", nativeQuery = true)
|
||||||
List<Object[]> findActiveCustomerTrend(@Param("startDate") LocalDate startDate,
|
List<Object[]> findActiveCustomerTrend(@Param("startDate") LocalDate startDate,
|
||||||
|
|
|
||||||
|
|
@ -124,10 +124,14 @@ public class CustomerService {
|
||||||
day = LocalDate.parse(row[0].toString());
|
day = LocalDate.parse(row[0].toString());
|
||||||
}
|
}
|
||||||
long count = ((Number) row[1]).longValue();
|
long count = ((Number) row[1]).longValue();
|
||||||
|
long added = ((Number) row[2]).longValue();
|
||||||
|
long removed = ((Number) row[3]).longValue();
|
||||||
|
|
||||||
result.add(CustomerActiveTrendPointDto.builder()
|
result.add(CustomerActiveTrendPointDto.builder()
|
||||||
.date(day)
|
.date(day)
|
||||||
.count(count)
|
.count(count)
|
||||||
|
.added(added)
|
||||||
|
.removed(removed)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue