######### KPI3 해결 과정 #########
목표
9.KPI3
조회기간 : 1주일-> 1달 로변경
탭 추가 : 전체,1,2,3,4
가열로 당 A,B
A = 실적입열량 -> TB_FUEL_KPI_Model Date,Fce_No,Gas_Flow
B = 예측입열량 -> TB_FUEL_KPI Date,Fce_No,Gas_Flow
C = A/B 비례개수
result = C의 표준편차
기본 계산공식 A,B,C
A,B 도출 공식:
0700~1900 오전 Sum(A),Sum(B) ,C = Sum(A)/Sum(B)
1900~0700 오후 Sum(A),Sum(B) ,C = Sum(A)/Sum(B)
result = avg(C) 의 표준편차
######### KPI3 해결 과정 #########
테이블에 있는 데이터 확인
TB_FUEL_KPI ->예측
TB_FULE_KPI_MODEL ->실측
테이블 모양(간략화)
DATESTART,DATEEND,GAS_FLOW,FCE_NO
원하는 데이터
특정 기간내 의 하루를 오전 오후로 나눈 시간의
TB_FUEL_KPI_MODEL의 SUM(GAS_FLOW) as GAS_FLOW_A
TB_FUEL_KPI의 SUM(GAS_FLOW) as GAS_FLOW_B
값(FCE_NO당)
어려웠던 점
일단 쿼리로 전부 합계까지 구해서 해결하려고 조인이나 여러가지를 써봤는데 중복으로 계산이 되어서 sum값을 찾을수가 없었다
이유는 기준이 되는 데이터가 없다 (DATE가 같지않음)
그래서 여러 컬럼이 1:N이 되어버려서 중복 계산이 되는것
그리고 A,B를 한번에 컬럼으로 뽑아내는 쿼리도...결국 실패하여서
TABLE 이름으로 나누어서 쿼리를 짜서 클라이언트에서 A,B를 구분하기로 함
결국은 오전의 결과 쿼리 + 오후의 결과 쿼리
select *from(
SELECT FCE_NO, MIN(DateStart) as startDate, MAX(DateStart) as endDate, SUM(Gas_Flow) as Gas_Flow_A, 'TB_FUEL_KPI_MODEL' as table_name
FROM TB_FUEL_KPI_MODEL
where {0} <= DateStart and DateStart< {1}
GROUP by FCE_NO
union
Select FCE_NO, MIN(DateStart) as startDate,MAX(DateStart)as endDate,SUM(Gas_Flow) as Gas_Flow_B,'TB_FUEL_KPI' as table_name
from TB_FUEL_KPI
where
{0} <= DateStart and DateStart< {1}
Group by Fce_No
)AS b
이 쿼리를 하면 결과값은
FCE_NO, startDate,endDate,Gas_Flow,table_name
으로 결과값이 나온다
그러면 클라이언트에서 데이터를 위의 형식으로 모든 날짜에 대하여 받는다
컨버팅 과정은 dictionary와 새로운 데이터클래스를 정의하여서 해결했다.
정의한 데이터 클래스
public class KPI3_Datas
{
public int fce_no;
public string startDT;
public string endDT;
public double Gas_A; //Tablename 이 TB_FUEL_KPI_MODEL이라면 A
public double Gas_B; //Tablename이 TB_FUEL_KPI이라면 B
public KPI3_Datas(int fce_no,string startDT,string endDT,double Gas_A,double Gas_B)
{
this.fce_no = fce_no;
this.startDT = startDT;
this.endDT = endDT;
this.Gas_A = Gas_A;
this.Gas_B = Gas_B;
}
}
데이터를 한번 for문 쭉 돌리면 결국 A,B를 다 채울수 있다.
결론 :KPI3_Datas의 데이터는 두개의 데이터가 있어야 A,B가 다 찬다.
같은 데이터라는것은 key 값을
string key = x.Fce_No + x.endDate.Substring(0,9); //초단위 까지 말고 시단위 까지 같으면 같은걸로 쳐주자
///key 값 (enddate)값에 대한 dic가 있다면 비어있는 A,B중 하나를 채워준다.//string key = x.Fce_No + x.endDate.Substring(0, 10);
/////초단위 까지 말고 시단위 까지 같으면 같은걸로 쳐주자
//데이터가 이상한건지 매칭이 잘 안됨 9까지 줄이자
//20200702070000 => 2020070207 까지 줄이기 8까지 해야하나...
이런식으로 시간 + fce_no을 해서 데이터를 구분했다.
실제 컨버팅 함수
foreach (var x in currentData._kPI3Items) ///서버에서 받은 데이터를 모두 확인한다.
{
//if (x.Fce_No == null)
///key 값 (enddate)값에 대한 dic가 있다면 비어있는 A,B중 하나를 채워준다.//string key = x.Fce_No + x.endDate.Substring(0, 10);
/////초단위 까지 말고 시단위 까지 같으면 같은걸로 쳐주자//데이터가 이상한건지 매칭이 잘 안됨 9까지 줄이자//20200702070000 => 2020070207 까지 줄이기 8까지 해야하나...
string key = x.Fce_No + x.endDate.Substring(0,10); //초단위 까지 말고 시단위 까지 같으면 같은걸로 쳐주자\
if (dic_date.ContainsKey(key))
{
//기존데이터라면 부족한 데이터를 채워준다
if (x.table_name == "TB_FUEL_KPI_MODEL")
dic_date[key].Gas_A = x.Gas_Flow;
else
dic_date[key].Gas_B = x.Gas_Flow;
}
else
{
KPI3_Datas tmp;
///새로운 데이터가 들어왔다면 table 이름에 따라 A,B를 채워준다
switch (x.table_name)
{
case "TB_FUEL_KPI_MODEL":
//A 실측값 TB_FULE_KPI_Model
tmp = new KPI3_Datas(x.Fce_No, x.startDate, x.endDate, x.Gas_Flow, 0);
dic_date.Add(key, tmp);
break;
case "TB_FUEL_KPI":
//B 예측값 TB_FULE_KPI
tmp = new KPI3_Datas(x.Fce_No, x.startDate, x.endDate, 0, x.Gas_Flow);
dic_date.Add(key, tmp);
break;
}
}
}
댓글 없음:
댓글 쓰기