[DB] DB sql문 3
Q. 회사별 첫 거래일 날짜를 구하시오.
SELECT zcom.cname, min(t1)
FROM(
SELECT cid as s1, min(indate) as t1 FROM zpan
GROUP BY s1
UNION ALL
SELECT cid as s1, min(indate) as t1 FROM zmoney
GROUP BY s1
) as k LEFT JOIN zcompany as zcom on k.s1=zcom.id
GROUP BY s1
ORDER BY zcom.cname;
풀이 순서
1. 매출,매입 등의 날짜기록이 있는 zpan에서 회사별 최소날짜 거래일과
입금, 출금 등의 날짜기록이 있는 zmoney에서 회사별 최소날짜 거래일 그룹화 한 뒤 유니온 시켜 한 테이블로 나타낸다.
2. 이 결과값의 최소 거래 날짜를 구하기위해 min()함수를 쓰고, 회사명을 나타내기 위해 zcompany에 조인한다.
유의사항 :
· 우리는 회사명을 결과적으로 보여줘야하지만, 과정속에서는 id 번호를 가지고 SQL문 코드를 작성한다
· 그룹화도 회사id번호를 가지고 함.
그룹화를 하지 않으면 각각 id마다의 결과값이 아닌 랜덤의 한 개 결과값만 출력한다.
· union 을 할때는 필드 개수를 맞춰주는게 중요.
union 할 때 각 select문마다 알리아스(alias)를 써주는 이유는 합친후의 컬럼 이름을 동일하게 맞춰주는 용도로 사용하기 때문이지 그 이외의 의미는 없다.
· 서브쿼리는 ()안에 넣어서 사용하며 다른 쿼리 내부에 포함된 쿼리를 의미한다.
한 줄로 결과값을 표현하자고자 할때는 select절에 서브쿼리를 사용할 수 있다.
ex)
SELECT T1.C1 ,(SELECT AVG(T2.C1) FROM TEMP2 T2) FROM TEMP1 T1;
· left 조인은 select 절에 표시해줘야할 컬럼정보가 from절의 테이블에 없는경우, 다른 테이블에서 가져와서 select절에 보여줘야 할 때에만 사용
left join 할 때 자주 착각하는거.
ex)SELECT zcom.cname, SUM(t1) from ( ... ) as k LEFT JOIN zcompany as zcom on k.s1 = zcom.id
여기서 'k와 zcompany가 left join을 한다.' 기 때문에 as k LEFT JOIN zcompany as zcom on 까지가 join 구문이다.
on 뒤의 k.s1 = zcom.id 는 where절 조건일뿐이지, left join과는 상관없음.
select절에 zcom.cname을 쓰지 않으면 left join을 쓸 이유가 없음.
ex)
update zcompany
SET tmoney=smoney + IFNULL((SELECT sum(zpan.total) FROM zpan WHERE zpan.cid=zcompany.id and zpan.type='매출'),0)
- IFNULL((SELECT sum(zpan.total) FROM zpan WHERE zpan.cid=zcompany.id and zpan.type='매입'),0)
- IFNULL((SELECT sum(zmoney.money) FROM zmoney WHERE zmoney.cid=zcompany.id and zmoney.type='입금'),0)
+ IFNULL((SELECT sum(zmoney.money) FROM zmoney WHERE zmoney.cid=zcompany.id and zmoney.type='지급'),0);
· having 절은 '서브쿼리, where절 group by를 지나 select 까지 완성된 결과값'에 대한 조건을 걸 수 있는 문장.
ex) <> 0
는 0이 아니라는 의미.