통계 관리 수정
parent
378587ab00
commit
db1e071c07
@ -1,10 +1,14 @@
|
|||||||
package cokr.xit.fims.stat.service;
|
package cokr.xit.fims.stat.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import cokr.xit.base.code.CommonCode;
|
||||||
import cokr.xit.fims.stat.Stat;
|
import cokr.xit.fims.stat.Stat;
|
||||||
import cokr.xit.fims.stat.StatQuery;
|
import cokr.xit.fims.stat.StatQuery;
|
||||||
|
|
||||||
public interface StatService {
|
public interface StatService {
|
||||||
|
|
||||||
Stat getStatistics(StatQuery query);
|
Stat getStatistics(StatQuery statQuery, Map<String, List<CommonCode>> commonCodes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,320 @@
|
|||||||
|
package cokr.xit.fims.stat.service.bean;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import cokr.xit.base.code.CommonCode;
|
||||||
|
import cokr.xit.fims.cmmn.CmmnQuery;
|
||||||
|
import cokr.xit.fims.crdn.parsing.CodeConverter;
|
||||||
|
import cokr.xit.fims.stat.Stat;
|
||||||
|
import cokr.xit.fims.stat.StatItem;
|
||||||
|
import cokr.xit.fims.stat.StatQuery;
|
||||||
|
import cokr.xit.foundation.AbstractComponent;
|
||||||
|
import cokr.xit.foundation.data.DataObject;
|
||||||
|
|
||||||
|
|
||||||
|
@Component("statBean")
|
||||||
|
public class StatBean extends AbstractComponent {
|
||||||
|
|
||||||
|
/**통계요청에 따라 데이터목록에서 통계를 생성한다.
|
||||||
|
* @param queryResult SQL쿼리 처리 결과, statQuery 통계 요청
|
||||||
|
* @return 통계
|
||||||
|
*/
|
||||||
|
public Stat groupByCartegory(List<DataObject> queryResult, StatQuery statQuery) {
|
||||||
|
|
||||||
|
Stat stat = new Stat();
|
||||||
|
|
||||||
|
//통계 요청 설정
|
||||||
|
int compositeSize = 0;
|
||||||
|
|
||||||
|
String[] compositeNumberValueSeperator = statQuery.getCompositeNumberValueSeperator();
|
||||||
|
String[] aggregateType = statQuery.getAggregateType();
|
||||||
|
|
||||||
|
if(compositeNumberValueSeperator == null && aggregateType == null) {
|
||||||
|
compositeSize = 1;
|
||||||
|
compositeNumberValueSeperator = new String[] {""};
|
||||||
|
aggregateType = new String[] {"count"};
|
||||||
|
} else if(compositeNumberValueSeperator != null && aggregateType == null) {
|
||||||
|
compositeSize = compositeNumberValueSeperator.length;
|
||||||
|
aggregateType = new String[compositeSize];
|
||||||
|
} else if(compositeNumberValueSeperator == null && aggregateType != null) {
|
||||||
|
compositeSize = aggregateType.length;
|
||||||
|
compositeNumberValueSeperator = new String[compositeSize];
|
||||||
|
} else {
|
||||||
|
if(compositeNumberValueSeperator.length > aggregateType.length) {
|
||||||
|
compositeSize = compositeNumberValueSeperator.length;
|
||||||
|
} else {
|
||||||
|
compositeSize = aggregateType.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i < compositeSize; i++) {
|
||||||
|
if(compositeNumberValueSeperator[i] == null) {
|
||||||
|
compositeNumberValueSeperator[i] = "";
|
||||||
|
}
|
||||||
|
if(aggregateType[i] == null || aggregateType[i].equals("")) {
|
||||||
|
aggregateType[i] = "count";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
statQuery.setAggregateType(aggregateType);
|
||||||
|
statQuery.setCompositeNumberValueSeperator(compositeNumberValueSeperator);
|
||||||
|
|
||||||
|
//통계 항목별 그룹핑
|
||||||
|
Map<String, List<DataObject>> group;
|
||||||
|
|
||||||
|
if(statQuery.getCategorization().length < 2) {
|
||||||
|
group = queryResult.stream()
|
||||||
|
.collect(Collectors.groupingBy(item -> item.string(statQuery.getCategorization()[0])));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
String[] categorizations = statQuery.getCategorization();
|
||||||
|
|
||||||
|
group = queryResult.stream()
|
||||||
|
.collect(
|
||||||
|
Collectors.groupingBy(
|
||||||
|
(item) -> {
|
||||||
|
String result = "";
|
||||||
|
for(int i = 0; i < categorizations.length; i++) {
|
||||||
|
if(i != 0) {
|
||||||
|
result += ",";
|
||||||
|
}
|
||||||
|
result += item.string(categorizations[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//고정 항목 설정
|
||||||
|
if(statQuery.getFixedItemId() != null) {
|
||||||
|
this.itemFix(group, statQuery.getFixedItemId());
|
||||||
|
}
|
||||||
|
|
||||||
|
//수치 값 추출
|
||||||
|
Set<String> keySet = group.keySet();
|
||||||
|
Iterator<String> it = keySet.iterator();
|
||||||
|
|
||||||
|
List<StatItem> statItems = new ArrayList<>();
|
||||||
|
while(it.hasNext()){
|
||||||
|
String key = it.next();
|
||||||
|
StatItem statItem = new StatItem();
|
||||||
|
|
||||||
|
if(statQuery.getCategorization().length < 2) {
|
||||||
|
statItem.setItemId(key);
|
||||||
|
} else {
|
||||||
|
statItem.setCompositeItemId(key.split(","));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DataObject> listByKey = group.get(key);
|
||||||
|
|
||||||
|
int[] numberValues = this.extractNumberValue(listByKey, statQuery);
|
||||||
|
|
||||||
|
statItem.setNumberValue(numberValues);
|
||||||
|
|
||||||
|
statItems.add(statItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
stat.setStatItems(statItems);
|
||||||
|
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 통계에 고정적으로 표시할 항목을 설정한다.
|
||||||
|
* @param group 그룹핑한 데이터 목록, fixedItemId 고정적으로 표시할 통계 항목 ID;
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public void itemFix(Map<String, List<DataObject>> group, String[] fixedItemId) {
|
||||||
|
|
||||||
|
for(int i=0; i < fixedItemId.length; i++) {
|
||||||
|
if(!group.containsKey(fixedItemId[i])) {
|
||||||
|
group.put(fixedItemId[i], null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> keySet = group.keySet();
|
||||||
|
Iterator<String> it = keySet.iterator();
|
||||||
|
|
||||||
|
List<String> deleteTargets = new ArrayList<>();
|
||||||
|
|
||||||
|
while(it.hasNext()) {
|
||||||
|
String key = it.next();
|
||||||
|
if(!Arrays.asList(fixedItemId).contains(key)) {
|
||||||
|
deleteTargets.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(String deleteTarget : deleteTargets) {
|
||||||
|
group.remove(deleteTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**통계요청에 따라 수치값(합계, 건수)을 계산한다.
|
||||||
|
* @param listByKey 특정 범주로 묶인 데이터 목록, statQuery 통계 요청
|
||||||
|
* @return 수치값
|
||||||
|
*/
|
||||||
|
public int[] extractNumberValue(List<DataObject> listByKey, StatQuery statQuery) {
|
||||||
|
|
||||||
|
String[] compositeNumberValueSeperator = statQuery.getCompositeNumberValueSeperator();
|
||||||
|
String[] aggregateType = statQuery.getAggregateType();
|
||||||
|
|
||||||
|
int[] aggregateArr = new int[compositeNumberValueSeperator.length];
|
||||||
|
for(int i=0; i < compositeNumberValueSeperator.length; i++) {
|
||||||
|
aggregateArr[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(listByKey != null) {
|
||||||
|
for(int i=0; i<listByKey.size(); i++) {
|
||||||
|
|
||||||
|
DataObject dataObject = listByKey.get(i);
|
||||||
|
|
||||||
|
for(int j=0; j < aggregateArr.length; j++) {
|
||||||
|
|
||||||
|
String condition = compositeNumberValueSeperator[j];
|
||||||
|
|
||||||
|
if(condition.contains("=")) {
|
||||||
|
|
||||||
|
String conditionColumn = condition.split("=")[0];
|
||||||
|
String conditionColumnValue = dataObject.string(conditionColumn);
|
||||||
|
String conditionValue = condition.split("=")[1];
|
||||||
|
|
||||||
|
if(conditionColumnValue.equals("")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(conditionColumn.endsWith("_DT") && conditionValue.length() == 8) {
|
||||||
|
conditionColumnValue = conditionColumnValue.substring(0,8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!conditionColumnValue.equals(conditionValue)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(aggregateType[j].startsWith("sum=")) {
|
||||||
|
aggregateArr[j] += dataObject.number(aggregateType[j].split("=")[1]).intValue();
|
||||||
|
} else {
|
||||||
|
aggregateArr[j] += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return aggregateArr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 특정 범주로 묶인 통계 항목에 항목명을 추가한다.
|
||||||
|
* @param statItems 통계 항목 목록, categoryNameConverter 항목명 변환 처리용 코드그룹명, allCode 코드 목록
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public void attachItemName(List<StatItem> statItems, String[] categoryNameConverter, Map<String, List<CommonCode>> allCode) {
|
||||||
|
|
||||||
|
CodeConverter codeConverter = new CodeConverter(allCode);
|
||||||
|
|
||||||
|
if(categoryNameConverter.length > 1) {
|
||||||
|
String[] codeGroups = categoryNameConverter;
|
||||||
|
for(StatItem statItem : statItems) {
|
||||||
|
|
||||||
|
String[] compositeItemId = statItem.getCompositeItemId();
|
||||||
|
String[] compositeItemName = new String[compositeItemId.length];
|
||||||
|
for(int i=0; i < compositeItemId.length ;i++) {
|
||||||
|
if(codeGroups[i].equals("")) {
|
||||||
|
compositeItemName[i] = compositeItemId[i];
|
||||||
|
} else {
|
||||||
|
String itemName = codeConverter.codeToValue(codeGroups[i], compositeItemId[i]);
|
||||||
|
compositeItemName[i] = itemName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statItem.setCompositeItemName(compositeItemName);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(StatItem statItem : statItems) {
|
||||||
|
String itemId = statItem.getItemId();
|
||||||
|
String itemName = codeConverter.codeToValue(categoryNameConverter[0] , itemId);
|
||||||
|
statItem.setItemName(itemName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 통계의 일부 항목을 합쳐 새 범주로 묶는다.
|
||||||
|
* @param statItems 통계 항목 목록, regroupInfos 재그룹화 정보
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public void regroupItem(List<StatItem> statItems, String[] regroupInfos) {
|
||||||
|
|
||||||
|
for(int i=0; i < regroupInfos.length; i++) {
|
||||||
|
|
||||||
|
String[] regroupInfo = regroupInfos[i].split("=");
|
||||||
|
String[] sourceCodes = regroupInfo[0].split(",");
|
||||||
|
String targetCodeName = regroupInfo[1];
|
||||||
|
|
||||||
|
StatItem newItem = new StatItem();
|
||||||
|
newItem.setItemId("regroup"+i);
|
||||||
|
newItem.setItemName(targetCodeName);
|
||||||
|
|
||||||
|
int[] numberValues = null;
|
||||||
|
|
||||||
|
for(StatItem statItem : statItems) {
|
||||||
|
if(Arrays.asList(sourceCodes).contains(statItem.getItemId())) {
|
||||||
|
if(numberValues == null) {
|
||||||
|
numberValues = statItem.getNumberValue();
|
||||||
|
} else {
|
||||||
|
for(int j=0; j < numberValues.length; j++) {
|
||||||
|
numberValues[j] += statItem.getNumberValue()[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newItem.setNumberValue(numberValues);
|
||||||
|
|
||||||
|
statItems.removeIf(item -> Arrays.asList(sourceCodes).contains(item.getItemId()));
|
||||||
|
|
||||||
|
statItems.add(newItem);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**쿼리에서 날짜와 관련된 파라미터를 설정한다.
|
||||||
|
* @param sql처리용 query, dayCol 날짜조회용 컬럼, from 조회시작일, to 조회종료일
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public void daySetting(CmmnQuery someQuery, String dayCol, String from, String to) {
|
||||||
|
try {
|
||||||
|
if(dayCol.equals("REG_DT")) {
|
||||||
|
|
||||||
|
Method m0 = CmmnQuery.class.getDeclaredMethod("setSchDateOpt", String.class);
|
||||||
|
m0.invoke(someQuery, "regDt");
|
||||||
|
Method m1 = CmmnQuery.class.getDeclaredMethod("setSchDateFrom", String.class);
|
||||||
|
m1.invoke(someQuery, from);
|
||||||
|
Method m2 = CmmnQuery.class.getDeclaredMethod("setSchDateTo", String.class);
|
||||||
|
m2.invoke(someQuery, to);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if(dayCol.equals("CRDN_YMD")) {
|
||||||
|
Method m1 = someQuery.getClass().getDeclaredMethod("setSchCrdnYmdFrom", String.class);
|
||||||
|
m1.invoke(someQuery, from);
|
||||||
|
Method m2 = someQuery.getClass().getDeclaredMethod("setSchCrdnYmdTo", String.class);
|
||||||
|
m2.invoke(someQuery, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue