두 컬럼의 합계(총계)를 구하고싶습니다. 0 7 1,490

by 쿼리냠냠 [SQL Query] 합계 총계 [2018.10.19 16:31:18]


안녕하세요. SQL문에 대해 궁금한게 있어 문의드립니다.

 SQL문 예시입니다.

SELECT 
 orderDetail.storeName as '판매점',
 SUM( IF(orderDetail.status = 'card', orderDetail.price, 0)) AS '카드결제',
 SUM( IF(orderDetail.status = 'cash', orderDetail.price,0 ) ) AS '현금결제'
 FROM orderDetail
 GROUP BY orderDetail.storeName;

 

*SQL문 예제의 데이터*

판매점 카드결제 현금결제
야채가게 10000 20000
슈퍼마켓 10000 20000
과일가게 10000 20000
     



***** 제가 원하는 쿼리!!!! *****
 

판매점 카드결제 현금결제 총계
야채가게 10000 20000 90000
슈퍼마켓 10000 20000 90000
과일가게 10000 20000 90000
       


-     제가원하는 쿼리는 조회된 로우의 '카드결제금액'+ '현금결제'를 합한 총계컬럼을 추가하고싶습니다.
       아래와 같이하게되면 제가원하는 쿼리는 뽑을 수 있습니다.

SELECT 
 orderDetail.storeName as '판매점',
 SUM( IF(orderDetail.status = 'card', orderDetail.price, 0)) AS '카드결제',
 SUM( IF(orderDetail.status = 'cash', orderDetail.price,0 ) ) AS '현금결제'
 SUM( IF( orderDetail.status = 'card' || orderDetail.status = 'cash' 
        , orderDetail.price,0 ) ) AS '총계'
 FROM orderDetail
 GROUP BY orderDetail.storeName;

 

Q.1) 위의쿼리대로 뽑게되면 제가원하는 데이터를 뽑을 수는 있습니다.
       하지만, 예제쿼리가아닌 실제 쿼리를 돌리는 경우 IF문의 조건이 많고 까다롭습니다.  
       총계를 구하기위해서 IF문이 길어지다보니.... 위의방법처럼 총계를 구하는 방법말고 다른 방법이 있는지 문의드립니다. 
     
       저는 SELECT 조회 시
       계산된 컬럼인 ['카드결제'/'현금결제']를 활용하여 총계를 내고싶습니다.

*원하는쿼리는 다음과 같습니다.*
- 조회된 로우데이터들의 '카드결제'컬럼과 '현금결제'컬럼의 총합을
  '총계'컬럼이라는 곳에 넣고싶습니다.

 

감사합니다. 좋은 하루보내세요!

by 우리집아찌 [2018.10.19 16:51:27]
WITH T (COMPANY,CARD_AMT,MONEY_AMT) AS (
SELECT '야채가게',10000,20000 FROM DUAL UNION ALL
SELECT '슈퍼마켓',10000,20000 FROM DUAL UNION ALL
SELECT '과일가게',10000,20000 FROM DUAL 
)
SELECT COMPANY , CARD_AMT , MONEY_AMT , SUM(CARD_AMT+MONEY_AMT) OVER() TOTAL_AMT
  FROM T

 


by 쿼리냠냠 [2018.10.19 17:18:18]

안녕하세요.

답변 감사드립니다.

주신 쿼리를 이해해본 후 적용시켜보도록 하겠습니다.

 

좋은 주말보내세요.


by 마농 [2018.10.19 16:57:59]

1. 쿼리 개선
  - 전체 공통 조건을 where 에 주고
  - 개별 조건을 If 로 주면 됩니다.
2. Group By 가 없네요?
  - mySql 에서만 허용되는 구문인데???
  - 표준 Group By 구문을 시용할 필요가 있습니다.
3. 나머지 부분도 표준쿼리로 바꿔봤습니다.
  - IF --> CASE
  - 알리아스 : 홑따옴표 -> 쌍따옴표

SELECT orderDetail.storeName AS "판매점"
     , SUM(CASE WHEN orderDetail.status = 'card' THEN orderDetail.price END) AS "카드결제"
     , SUM(CASE WHEN orderDetail.status = 'cash' THEN orderDetail.price END) AS "현금결제"
     , SUM(orderDetail.price) AS "총계"
  FROM orderDetail
 WHERE orderDetail.status IN ('card', 'cash')
 GROUP BY orderDetail.storeName
 ORDER BY orderDetail.storeName
;

 


by 쿼리냠냠 [2018.10.19 17:43:02]

안녕하세요.
답변감사드립니다.

답변에 대한 질문이있습니다.

1. 공통 조건은 where 개별조건은 if문 ( 나중에 쿼리를 짤때 공통과개별 생각하면서 짜는습관을 들여야겠습니다. 감사드립니다!)
==> 제가 실제로 원하는 조건절은 다음과같습니다.
        조건절 : [1] 2018년 8월에 판매된건이면서 [2] 카드결제이면서 [3] 2018년 9월에 취소된건의 합 
                     if문으로 한이유는 case when절에는  '||'(OR) 나 '&&'(AND)를 넣어도 먹질 않아서 입니다.   
                     EX) CASE WHEN status = 'card' AND orderDate = '2018-08' AND cancelDate ='2018-09' 
  Q.1) When의 CASE마다 AND조건절을 줄 수 있는 방법이있나요? 있다면 if문대신 적용해보도록해보겠습니다. 
         ( 테스트로 쿼리를 짤 때 먹질 않아서 IF문으로 대체하게되었습니다. )

2. Group BY가 없네요? 
    -> 본문에서 ORDER BY로 잘 못 썼습니다. (본문을 수정해 놓도록하겠씁니다.)
 

3. 주신 쿼리는 깔끔합니다. 
    하지만 제가 원하는 '총계'는 아닙니다.
    제가원하는 총계는 GROUP BY해서 '판매점들마다의 총계'가 아닌 
    조회된 '로우데이터들의 총합계' 입니다. 

* GROUP BY를 판매점으로 했기때문에 주신쿼리는 아래와같이나옵니다.  * 

판매점 카드결제 현금결제 총계
야채가게 10000 10000 20000
슈퍼마켓 5000 5000 10000
       

* 제가원하는데이터는 아래와같습니다.*
   

판매점 카드결제 현금결제 총계
야채가게 10000 10000 30000
슈퍼마켓 5000 5000 30000
       


*총계를 이렇게 내고싶은이유...* 
1. 실제로 데이터는 많습니다. 몇천개 ~ 만개정도
2. 클라이언트단이나 서버단에서 반복문을 돌려 '로우데이터들의 총합계'를 도출하는 것보다
    디비에서 '총계'를 가져오는것이 더 맞는 것 같아 쿼리문을 짜려고합니다.

 

감사합니다.

 

좋은 하루보내세요!

 


by 야신 [2018.10.20 22:42:12]

select case when (1 = 1 and 2 = 2 ) or ( 4= 4 ) then 'Y' else 'N' end

mysql 도 위와 같은 case 문이 잘 작동된는 것으로 알고 있는데 버젼이 어떻게 되시나요?


by 마농 [2018.10.22 08:46:15]

if 문은 잘되는데 case 문은 안된다는 건 좀 이상하구요?
분석함수 사용 가능 버전이라면? 간단하게 해결되구요. (MySQL 8 이상)
SUM(SUM(price)) OVER() AS 총계
그렇지 않다면? 좀 복잡해 집니다.
요구조건에 대한 설명이 명확하지 않아 조건절은 임의로 작성했습니다.

SELECT *
  FROM (SELECT storeName AS "판매점"
             , SUM(CASE WHEN status = 'card' THEN price END) AS "카드결제"
             , SUM(CASE WHEN status = 'cash' THEN price END) AS "현금결제"
             , SUM(price) AS "소계"
          FROM orderDetail
         WHERE orderDate = '2018-08'
           AND status IN ('card', 'cash')
           AND ( (status = 'card' AND cancelDate = '2018-09') OR
                 (status = 'cash'                           ) )
         GROUP BY storeName
        ) a
 CROSS JOIN
       (SELECT SUM(price) AS "총계"
          FROM orderDetail
         WHERE orderDate = '2018-08'
           AND status IN ('card', 'cash')
           AND ( (status = 'card' AND cancelDate = '2018-09') OR
                 (status = 'cash'                           ) )
        ) b
;

 


by 마농 [2018.10.22 10:38:05]

열을 추가하여 같은 값을 반복적으로 중복 표시하는 것 보다는
행을 추가하여 한번만 보여주는건 어떤가요?
 

SELECT IFNULL(storeName, '합계') AS "판매점"
     , SUM(CASE WHEN status = 'card' THEN price END) AS "카드결제"
     , SUM(CASE WHEN status = 'cash' THEN price END) AS "현금결제"
     , SUM(price) AS "합계"
  FROM orderDetail
 WHERE orderDate = '2018-08'
   AND status IN ('card', 'cash')
   AND ( (status = 'card' AND cancelDate = '2018-09') OR
         (status = 'cash'                           ) )
 GROUP BY storeName
  WITH ROLLUP
;

 

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