안녕하세요. 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 조회 시
계산된 컬럼인 ['카드결제'/'현금결제']를 활용하여 총계를 내고싶습니다.
*원하는쿼리는 다음과 같습니다.*
- 조회된 로우데이터들의 '카드결제'컬럼과 '현금결제'컬럼의 총합을
'총계'컬럼이라는 곳에 넣고싶습니다.
감사합니다. 좋은 하루보내세요!
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 ;
안녕하세요.
답변감사드립니다.
답변에 대한 질문이있습니다.
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. 클라이언트단이나 서버단에서 반복문을 돌려 '로우데이터들의 총합계'를 도출하는 것보다
디비에서 '총계'를 가져오는것이 더 맞는 것 같아 쿼리문을 짜려고합니다.
감사합니다.
좋은 하루보내세요!
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 ;
열을 추가하여 같은 값을 반복적으로 중복 표시하는 것 보다는
행을 추가하여 한번만 보여주는건 어떤가요?
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 ;