오라클 SQL 쿼리...
2013.11.19 01:25
질문하시기 전에 게시판 검색을 먼저 해주세요.
타블릿PC, 스마트폰에 관한 질문 또는 요청은 <포터블기기 질문답변> 게시판을 이용해주세요.
=============================================================================================
안녕하세요, 인포넷입니다...
오라클 SQL 쿼리에 대해서 질문이 있어서 이러렇게 글을 남깁니다...
Member 테이블 구조
Book 테이블 구조
Loan 테이블 구조
이렇게 위의 3개 테이블을 이용하여 아래와 같이 표시를 하고싶어요...
먼저...
위 처럼 뽑아내기 위해서 아래의 쿼리를 사용했습니다...
select m.memberno, m.name, m.nickname, m.phone, m.mobilephone, count(m.memberno) as noret
from loan l join member m on l.memberno = m.memberno
join book b on l.bookno = b.bookno
where l.returndate is null
group by m.memberno, m.name, m.nickname, m.phone, m.mobilephone
그리고...
위 처럼 뽑아내기 위해서 아래의 쿼리를 사용했습니다...
select m.memberno, m.name, count(m.memberno) as over
from loan l join member m on l.memberno = m.memberno
join book b on l.bookno = b.bookno
where l.returndate is null and l.duedate < sysdate
group by m.memberno, m.name
위의 두 쿼리를 어떻게 조합을 하면 위에 보인대로 표시할 수 있을 것 같은데 도무지 어떻게 해야 할지 모르겠네요...
좀 도와주세요...
답변 주시는 분들께 미리 감사인사 드립니다...
코멘트 7
-
전설의주부용사
11.19 07:07
-
김강욱
11.19 10:03
select m.memberno, m.name, m.nickname, m.phone, m.mobilephone, count(m.memberno) as noretfrom loan l joinmember mon l.memberno = m.memberno joinbook bon l.bookno = b.booknowhere l.returndate is nullgroup by m.memberno, m.name, m.nickname, m.phone, m.mobilephoneselect m.memberno, m.name, count(m.memberno) as overfrom loan l joinmember mon l.memberno = m.memberno joinbook bon l.bookno = b.booknowhere l.returndate is nulland l.duedate < sysdategroup by m.memberno, m.name정리해서 보니, 쿼리가 거의 동일하네요.특히, group by 파트는 둘 다group by m.memberno 로 하셔도 무방한 것 같은데, 맞나요? 그래야 뒷 얘기가 풀려서(group by m.memberno 로 하시고 select 절에는 max(m.name) name 같은 식으로 group function 을 쓰셔야 함)select m.memberno, max(m.name) name, count(if (l.duedate < sysdate, m.memberno, null)) as over,count(m.memberno) as noretfrom loan l joinmember mon l.memberno = m.memberno joinbook bon l.bookno = b.booknowhere l.returndate is nullgroup by m.memberno아, 참 저 if 는 oracle 에서는 decode 였던것 같은데. -_-;;;;큰 집합에서 작은 집합을 도출하는 건 한번으로 다 가능합니다.왠만한 통계자료도 복제 아니면 어낼리틱 펑션으로 해결가능하구요.요쪽 공부 좀 하시면 도움 많이 되실겁니다. -
인포넷
11.21 01:37
답변을 달아주신 두분 감사합니다...
답변을 찾았습니다...
with a as (
select memberno, count(*) count1
from loan
where returndate is null
group by memberno),
b as (
select memberno, count(to_char(memberno)) count2
from loan
where returndate is null and duedate < (sysdate - 1)
group by memberno)
select m.memberno, m.name, m.nickname, m.phone, m.mobilephone,
a.count1 as noret,b.count2 as over
from a, b, member m
where a.memberno = m.memberno and b.memberno = m.memberno; -
조슈아
11.21 10:32
음.. 인포넷님.
제가 돌려 보진 안아서 확실하지는 않지만 위에 퀴리는 문제가 좀 있습니다.m table 전체 회원 목록 (예를 들어 100명)
a view (with a as 부분) 은 전체 대출한 사람의 집합 이고 (예를 들어 10명)
b view (with b as 부분) 은 대출한 사람 중에 연체 된 사람의 집합 이 되는 데 (예를 들어 3명)
3개 테이블을 join 을 한다는 것은 교집합을 구하는 건데..
그러면 결국 3개 테이블 중에 가장 작은 테이블에 맞추어서 (3개)만 출력 될 겁니다.
(물론 제가 돌려보고 이야기 하는게 아니라 제가 퀴리를 잘못 해석 했을 수도 있습니다.)해결 방법은
전설의주부용사님의 말 처럼
b view 쪽에 outer join 을 걸어서 없더라도 null 로 나올 수 있게 하거나
김강욱님 말 처럼
로직으로 해당 경우에만 count 되도록 걸러서 보여주는 방법으로 하면 될거 같습니다. -
인포넷
11.21 15:00
답변 감사합니다...
조슈아님 말씀대로...
"그러면 결국 3개 테이블 중에 가장 작은 테이블에 맞추어서 (3개)만 출력 될 겁니다."
3개 출력을 원하는 것이었어요...
-
김강욱
11.21 10:53
보통 인포넷님 방식의 쿼리가 엑셀이 대용량을 처리 못하는 이유기도 한 것으로 유추하는데요.
1차적으로 같은 테이블을 3번 읽게 되어서 문제가 좀 발생할 수 있구요. 건수가 많으면 좀 문제가 되겠지요.
그걸 차치하더라도, 저게 만약 Nested 로 풀린다면 a 가 드라이빙되어서 b 를 풀때, b 에 인덱스가 없어서 b Inline view full scan 하는 현상이 있을 듯 합니다.
아마 오라클 같은 경우는 해쉬 조인을 하게 될 것 같은데요. 그래도 해쉬 로드는 무시할 양은 아니라고 생각이 드네요.
-
인포넷
11.21 15:01
답변 감사합니다...
지금은 공부 단계라서 결과만 나오면 되는 것이어요...
실무에서 사용하기엔 좀 문제가 있겠군요...
저도 공부 하고 있는 입장이라 ..해당 테이블 때려넣어서 join 때려넣어봐야 알것같은데요
조건이
member,book,loan 이 3개의 각테이블에서 각 컬럼과 일치하는 값이 같다는 가정하에..
ansi outer join 으로 해당 테이블 3개를 join 처리하시면 되지 않을까요...
공부하시는데 도움 주는 사이트 중에 데이터 베이스 포럼에 가시면 정리가 재법 잘되어있더라고요.