by 흰둥이 [SQL Query] postgresql.쿼리 조인 join SQL SELECT [2024.09.19 10:31:10]
SELECT COALESCE(CASE WHEN N11.NORM_IRRT BETWEEN TO_NUMBER(N10.STR_VLU) AND TO_NUMBER(N10.END_VLU)
THEN N10.VLU
END,'합계') AS VLU
, SUM(CASE WHEN N11.COND2 = '10' THEN N11.BAL ELSE 0 END) AS BAL
FROM A_TABLE N10
LEFT OUTER JOIN
B_TABLE N11
ON N10.MGNT_NO = 'AAA'
AND N10.CD_ID = 'BBB'
AND TO_CHAR(LAST_DAY(('${BASC_YM}'||'01')::DATE),'YYYYMMDD') BETWEEN N10.STR_DT AND N10.END_DT
AND N11.BASC_YM = '${BASC_YM}'
AND N11.DV_CD1 = 'A'
AND N11.DV_CD2 = 'B'
AND CASE WHEN COALESCE('${COND1}','') = '' THEN 1=1
ELSE N11.COND1 = '${COND1}'
END
AND CASE WHEN COALESCE('${COND2}','') = '' THEN 1=1
WHEN '${COND2}' = '1' THEN N11.COND2 IN ('10','20')
WHEN '${COND2}' = '2' THEN N11.COND2 IN ('30','40','50')
END
AND N11.NORM_IRRT BETWEEN TO_NUMBER(N10.INVL_STR_VLU) AND TO_NUMBER(N10.INVL_END_VLU)
AND (
CASE WHEN N11.NORM_IRRT BETWEEN TO_NUMBER(N10.STR_VLU) AND TO_NUMBER(N10.END_VLU)
THEN N10.VLU
END
) IS NOT NULL
GROUP BY ROLLUP
((
CASE WHEN N11.NORM_IRRT BETWEEN TO_NUMBER(N10.INVL_STR_VLU) AND TO_NUMBER(N10.INVL_END_VLU)
THEN N10.CD
END
))
이런 쿼리를 작성하는데 A_TABLE 의 모든 ROW가 나오게 하고싶어서 아우터조인 건건데 안나오네요,, 어떤걸 수정하면 될까요 ㅠㅠ
B_TABLE 을 서브쿼리로 가져와서 조건절을 다 없애야할까요??
1. 일단 where 절이 없으므로
- n11 과의 조인에 실패해도 N10 의 자료는 모두 다 나오게 됩니다.
- 그런데? N10 에 대한 조건은 WHERE 절로 빼야 하는게 아닌지?
2. 그룹바이 하기 전 데이터 확인 하셨나요?
- 그룹바이 롤업하면서, 조인 실패데이터와 롤업 데이터가 둘 다 합계로 표현될 것 같습니다.
- 조인 실패 데이터는 합계가 아닌 기타로 표현되도록 개선 필요
3. 그룹바이 쿼리가 이상한데요?
- 그룹바이 항목(THEN n10.cd)과 SELECT 항목(THEN n10.vlu)이 다른데요?
- 이 부분도 확인 필요합니다. (표준 그룹바이 구문이 아님)
4. CASE WHEN 절의 조건이
- ON 절로 내려가야 하는것은 아닌지?
- CASE WHEN n11.norm_irrt BETWEEN TO_NUMBER(n10.str_vlu) AND TO_NUMBER(n10.end_vlu)
5. 조건절에서는
- (10,20) 또는 (30,40,50) 을 가져오는데?
- Select 절의 sum 에서는 10 만 가져오는게 맞는건지?
SELECT n10.cd , n10.vlu , SUM(n11.bal) bal FROM a_table n10 LEFT OUTER JOIN b_table n11 ON n11.basc_ym = '${BASC_YM}' AND n11.dv_cd1 = 'A' AND n11.dv_cd2 = 'B' AND (COALESCE('${COND1}', '') = '' OR n11.cond1 = '${COND1}') AND ( (COALESCE('${COND2}', '') = '') OR ('${COND2}' = '1' AND n11.cond2 IN ('10','20')) OR ('${COND2}' = '2' AND n11.cond2 IN ('30','40','50')) ) AND n11.norm_irrt BETWEEN TO_NUMBER(n10.invl_str_vlu) AND TO_NUMBER(n10.invl_end_vlu) WHERE n10.mgnt_no = 'AAA' AND n10.cd_id = 'BBB' AND TO_CHAR(LAST_DAY(('${BASC_YM}'||'01')::DATE), 'yyyymmdd') BETWEEN n10.str_dt AND n10.end_dt GROUP BY ROLLUP ((n10.cd, n10.vlu)) ;