그룹별 SUM MAX값 한번에 구하기 0 18 4,389

by 구사일생 [SQL Query] GROUP별 SUM MAX [2025.03.21 20:40:08]


IMG_4430.jpeg (644,026Bytes)

A001지점   A002지점   A01상위부서
CODE VALUE   CODE VALUE   CODE VALUE
11110000 4000   11110000 4400   11110000 8400
11110001 3000   11110001 2000   11110001 5000
11110002 0.3   11110002 0.3   11110002 0.3
11110003 0.8   11110003 0.8   11110003 0.8
11110004 5000   11110004 5300   11110004 10300
11110005 5500   11110005 5200   11110005 10700
11110006 1.0   11110006 1.0   11110006 1.0

상위부서는 두 지점의 금액은 SUM하고 소수점 율은 MAX로 같은 값을 가져와야 합니다.

단순하게는 아래와 같이생각을 하였으나 문제는 CODE별 VLAUE값 즉, CODE의 ROW가 100개 정도 되어서 한번에 아래와 같이 

작성을 하기는 넘 지저분 하기도 해서 UNION ALL 말고 한번에 처리가 혹시 가능 할까요?

(참고로 어떤 CODE를 SUM할지 MAX를 할지 의 CODE관리가 따로 되어 있지는 않은 상황 임.)

SELECT
     'A01' --상위지점
   , CODE
   , SUM(VALUE)||'' AS VALUE
  FROM 지점
 WHERE CODE IN ('11110000','11110001','11110004','11110005')
 GROUP BY CODE
 UNION ALL
 SELECT
    'A01' --상위지점
   , CODE
   , MAX(VALUE)
  FROM 지점
 WHERE CODE NOT IN ('11110000','11110001','11110004','11110005') 
 GROUP BY CODE

by 마농 [2025.03.24 00:05:46]
1
2
3
4
5
6
7
8
9
SELECT 'A01' 상위지점
     , code
     , CASE WHEN code IN ('11110000','11110001','11110004','11110005')
            THEN SUM(value)
            ELSE MAX(value)
             END v
  FROM 지점
 GROUP BY code
;

 


by 구사일생 [2025.03.24 22:37:17]

ORA-00932 :inconsistenst datatypes: expected CHAR GOT NUMBER

위와 같은 메세지가 나는 데 SUM(value)||'' 이렇게 해결 되었습니다. 감사합니다.

SELECT 'A01' 상위지점
     , code
     , CASE WHEN code IN ('11110000','11110001','11110004','11110005')
            THEN SUM(value)||''
            ELSE MAX(value)
             END v
  FROM 지점
 GROUP BY code

한가지만 더 질문하겠습니다.

지점의 코드를 조건으로 조회 하면 상위부서의 코드와 같이 나오게 하려면 어떻게 하면 될까요?

A001 11110000    4000 <--WHERE 조건 지점
A01  11110000    8400 <--상위부서 CODE

금일 하루 종일 해 봤는데 실패 하여 UNION ALL로 하기는 했는데 너무 소스가 길어 져서 음 ~~~
아래 처럼 해보려고 했는데도(??)
SELECT
     ORGCD
   , CODE
   , VALUE
  FROM 매출 A
  LEFT OUTER JOIN 지점 B ON A.ORGCD = B.ORGCD
  LEFT OUTER JOIN 지점 C ON A.ORGCD = C.HG_ORGCD --상위코드
 WHERE CODE = '11110000'
   AND 지점 = 'A001'
;


by 마농 [2025.03.25 08:31:15]

1. value 가 문자인 듯 한데
문자에 MAX 를 하면 올바른 결과가 안나올 수 있습니다.
예) 문자로는 '10.0' 보다 '9.9' 가 더 큼
SUM 결과를 문자로 바꾸는게 아니라
MAX 하기 전 value 를 숫자로 바꿔야 합니다.
그리고 value 와 같은 시스템 예약어를 컬럼명으로 사용하는 것은 좋지 않습니다.

2. 질문이 모호합니다.
원본이 어떤 형태인지?
원하는 결과물이 어떤 형태인지?
원본 대비 결과표 형태로 정확하게 질문해 주세요.


by 구사일생 [2025.03.25 21:02:07]

1.말씀하신 대로 MAX 하기 전에 *1을 하여 처리 하였습니다.
2.이건 질문 자체가 어렵네요 어떻게 설명을 해야 하나 음 ~~

걍 제가 하려고 하는 결과를 말씀 드릴게요

예시를 든 A001지점과 A002지점을 읽어서 같은 테이블에 A01상위부서를 만들어서 INSERT 해야 합니다.
물론 그때 CODE에 따라 SUM OR MAX해서 INSERT 합니다.

문제는 그 다음 부터 입니다.

아래의 CASE문 같은 내용을 반영 해야 하나 값이 같은 행에 존재 하지 않고
ROW가 나눠져 한번에 연산을 할수가 없습니다.

/*예시 데이터*/
A001 11110000    4000 <--WHERE 조건 지점
A01  11110000    8400 <--상위부서 CODE

SELECT 
      CASE WHEN CODE = '11110000' THEN A001.매출 + (A001.매출)*0.5
           WHEN CODE = '11110004' THEN A001.매출 - A001.매출
           END
  FROM BASE_SALE A
  LEFT OUTER JOIN 지점 B PM A.지점 = B.지점
  LEFT OUTER JOIN 지점 C PM A.지점 = C.상위지점(??)
 WHERE 1=1
   AND 지점 = 'A001'
   
현재는 UNION ALL로 분리 해서 억지로 처리는 하였으나 지점갯수와 CODE갯수가 많아 소스가 엄청 지저분 하네요


by 마농 [2025.03.25 23:59:44]

원본 데이터의 형태를 알아야 답변 가능합니다.
현재 완성된 쿼리가 있으면 그걸 보여주시던가요.
지금 엉성하게 보여주시는 쿼리는
질문할 때마다 테이블명, 컬럼명 등등이 계속 바뀌고 있고
부정확하고 모호하여 질문의 요지를 파악하기에 오히려 방해가 되고 있습니다.
이런식으로는 도움 드리기 어렵습니다.
코드와 상위코드와의 관계가 어떤 형태로 구성되어 있는지?
합계를 구하려는 항목은 어느 테이블에 존재하는지? 등등
원본 대비 결과표로 질문해 주시는게 좋습니다.


by 구사일생 [2025.03.26 20:31:48]

실제로 소스에 반영한 내용을 일부 발췌 했습니다.

현재 개발 중이어서 개선은 필요해 보여서 지속 적으로 문의 를 한 것입니다.

PIVOT으로도 함 고민 해 봤는데 지점코드가 여러개고 또한, 1년에 2번이상 지점의 상위부서 정보가 변경 됩니다.

(매출이 좋은 지점을 하위로 둔 부서의 인센티브를 고루 나눠 가질수 있계 상위 부서을 변경 함.)

WITH T_SALE AS (
SELECT '202412' BASE_YM, '51329500' ACCT_CD. '110522' ORGCD, 103334 AMT FROM DUAL UNION ALL
SELECT '202412' BASE_YM, '51329500' ACCT_CD. '109816' ORGCD, 2537766 AMT FROM DUAL UNION ALL
SELECT '202412' BASE_YM, '51333100' ACCT_CD. '110522' ORGCD, 675790 AMT FROM DUAL UNION ALL
SELECT '202412' BASE_YM, '51333100' ACCT_CD. '109821' ORGCD, 4445320 AMT FROM DUAL
)
, T_ORG AS (
SELECT '202412' BASE_YM, '110522' ORGCD, '1본부' ORGNM, '' HGRK_ORGCD FROM DUAL UNION ALL
SELECT '202412' BASE_YM, '109816' ORGCD, '1본부_1팀' ORGNM, '110522' HGRK_ORGCD FROM DUAL UNION ALL
SELECT '202412' BASE_YM, '109821' ORGCD, '1본부_2팀' ORGNM, '110522' HGRK_ORGCD FROM DUAL
)
SELECT
      T1.BASE_YM
    , T1.ORGCD
    , T1.ACCT_CD
    , T1.AMT
    , T1.HGRK_ORGCD
    , T2.AMT
  FROM ( /*지점 데이터 조회*/
        SELECT
               A.BASE_YM
             , A.ORGCD
             , A.ACCT_CD
             , A.AMT
             , B.HGRK_ORGCD
         FROM T_SALE A
         LEFT OUTER JOIN T_ORG B ON A.BASE_YM = B.BASE_YM AND A.ORGCD = B.ORGCD
        WHERE 1=1
          AND A.ORGCD IN ('109816','109821')
      ) T1
  LEFT OUTER JOIN ( /*상위부서 데이터 조회*/
                   SELECT
                          A.BASE_YM
                        , A.ORGCD
                        , A.ACCT_CD
                        , A.AMT
                    FROM T_SALE A
                    LEFT OUTER JOIN T_ORG C ON A.BASE_YM = C.BASE_YM AND A.ORGCD = C.ORGCD
                   WHERE 1=1
                     AND A.ORGCD = '110522'
      ) T2 ON T1.BASE_YM = T2.BASE_YM AND T1.HGRK_ORGCD = T2.ORGCD AND T1.HGRK_ORGCD = T2.HGRK_ORGCD


by 마농 [2025.03.26 23:27:12]

원본을 만들어 주셨네요.
이제 원본 대비 원하는 결과표도 만들어 주시면 됩니다.
상하위 관계가 테이블 자료를 통해 이미 정해져 있으므로
작성하신 코드와 같이 조건절 하드코딩은 불필요 합니다.
원하시는 결과표만 원본대비로 해서 정확하게 제시해 주시면 됩니다.


by 구사일생 [2025.03.27 08:42:28]

원하는 결과는 위 sql에서 T1 T2를 2번 따로 각각 조회 하지 않고 한번만 조회 하고 결과가 위 처럼 나 왔 으면 합니다

암튼 위에서 처럼 말고 조금만 간결 했으면 합니다


by 마농 [2025.03.27 09:33:12]

글로 적지 마시고 표로 보여주세요.
원본의 데이터를 기반한 정확한 결과값 표시


by 구사일생 [2025.03.27 10:03:34]

핸드폰으로 사진을 찍었는데 이미지를 어떻게 올리나요


by 구사일생 [2025.03.27 10:16:54]

회사에서는 파일 첨부가 안 된다고 하네요 인터넷도 신호가 약해서 집에서 올릴게요 


by 마농 [2025.03.27 10:19:50]

그냥 위에 with 문으로 만들어 주신 원본 예시자료로
원본 대비 결과표를 만들어 주시면 됩니다.
몇건 안되는데요. 엑셀로 금방 할 것 같은데요?


by 구사일생 [2025.03.27 10:25:30]

엑셀로 했어요 그런데 파일이 첨부가 되질 않네요 저도 답답하네요


by 구사일생 [2025.03.27 10:34:02]

등록 했어요


by 구사일생 [2025.03.27 10:40:28]

회사에서는 컴터는 인터넷이 되질 않아서 핸폰으로 하려니 어렵네요


by 마농 [2025.03.27 10:54:44]

그냥 타이핑 몇번만 해주시면 되는데...
이미지로 올려주시면 테스트 하기 위해 제가 타이핑 해야 합니다.


by 마농 [2025.03.27 11:05:44]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
WITH t_sale AS
(
SELECT '202412' base_ym, '51329500' acct_cd, '110522' orgcd,  103334 amt FROM dual
UNION ALL SELECT '202412', '51329500', '109816', 2537766 FROM dual
UNION ALL SELECT '202412', '51333100', '110522',  675790 FROM dual
UNION ALL SELECT '202412', '51333100', '109821', 4445320 FROM dual
)
, t_org AS
(
SELECT '202412' base_ym, '110522' orgcd, '1본부' orgnm, '' hgrk_orgcd FROM dual
UNION ALL SELECT '202412', '109816', '1본부_1팀', '110522' FROM dual
UNION ALL SELECT '202412', '109821', '1본부_2팀', '110522' FROM dual
)
SELECT a.base_ym
     , a.orgcd
     , b.acct_cd
     , b.amt
     , a.hgrk_orgcd
     , c.amt hgrk_amt
  FROM t_org  a
     , t_sale b
     , t_sale c
 WHERE a.base_ym    = b.base_ym
   AND a.orgcd      = b.orgcd
   AND a.base_ym    = c.base_ym
   AND a.hgrk_orgcd = c.orgcd
   AND b.acct_cd    = c.acct_cd
   AND a.base_ym    = '202412'
--   AND a.hgrk_orgcd = '110522'
;

 

예시자료만 봐서는 집계가 필요 없어 보이는데
집계가 필요하다면 좀더 복잡한 예시자료 만들어 주세요.
부서명은 출력 안해도 되는 것인지?
이전 질문에 잇었던 CASE 문은 필요 없는 것인지? 등등
원하시는 방향을 모두 아우를 수 있는 예시자료 만들어 보세요.


by 구사일생 [2025.03.27 20:21:11]

급한 일 마무리 하고 이제야 집에와서 답글 답니다.

회사 PC에서는 인터넷이 되질 않아 핸드폰으로 찍고 부득히 이미지를 올렸습니다. 죄송하고 감사합니다.

보내 주신 팁만으로도 원하는 답을 얻었습니다. 올려 주신 내용으로 금일 배치 수정을 완료 하였습니다. 

올려주신 내용을 상세히 확인 해 보니 T_ORG테이블을 먼저 읽는게 제게는 HIT였습니다.

T_SALE 테이블을 2번 조회하는건 저도 그렇게 하고 있었는데 ... 암튼 답변 글을 활용해 완성하였네요 감사합니다.

급한 마음에 생각없이 질문만 하여 혼선을 드린점 다시 한번 송구 하고 감사합니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입