2020년 8월 12일 수요일

[쿼리] 그룹 by Group by 컬럼

 

######### 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(DateStartas startDate, MAX(DateStartas endDate, SUM(Gas_Flowas 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(DateStartas 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_NOstartDate,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_Nox.startDatex.endDatex.Gas_Flow0);
                        dic_date.Add(keytmp);
                        break;
                    case "TB_FUEL_KPI":
                        //B 예측값 TB_FULE_KPI
                        tmp = new KPI3_Datas(x.Fce_Nox.startDatex.endDate0x.Gas_Flow);
                        dic_date.Add(keytmp);
                        break;
                }
            }
        }

























댓글 없음:

댓글 쓰기

git rejected error(feat. cherry-pick)

 문제 아무 생각 없이 pull을 받지않고 로컬에서 작업! 커밋, 푸시 진행을 해버렷다. push에선 remote와 다르니 당연히 pull을 진행해라고 하지만 로컬에서 작업한 내용을 백업하지 않고 진행하기에는 부담스럽다(로컬작업 유실 가능성) 해결하려...