이 검색 결과가 이해가 안됩니다 ㅜ 0 5 1,613

by 김태성 [SQL Query] [2015.06.11 10:03:32]


안녕하세요, 타블렛으로 ㅆ는거라 오타가 많은점 이해부탁드립니다.

책보고 공부중인데 주문한 노트북이 내일 도착이라 확인도 못하고 너무 답답해서 구루비에 도움 요청합니다.

테이블명 sales

Year  sale

1990 50

1992 50

1993 52

1994 55

1997 55

이 테이블에 대해서 직전의 년도와 sale 값이 같은 것. 즉 1997년 1992년을 검색.

이에대한 쿼리가 아래와 같습니다.

Select year, sale

From sales S1

Where sale =

   (Select sale

     From sales S2

     Whete S2.year =

          (Select max(year)

            From sales S3

            Where S1.year > S3.year))

이렇개 됩니다.

실행순서와 결과를 나름 여러각도로 생각해 봤는데 저 결과가 도저히 이해가 안갑니다...

일단 실행순서는 가장 안쪽에있는 Max치를 검색하는 select문이 실행되고.

같은 테이블 S1과 S3을 비교하니까 

S1.     S3

1990 1990

1990 1992

1990 1993

중략

1997 1993

1997 1994

1997 1997

이렇게 25개를 s1(왼쪽)이 더 큰거는,그중 Max니까

1992 1990

1993 1992

1994 1993

1997 1994

이렇게 된다고 생각합니다. 일단 여기가 맞는지 애매하고 왜 s3와 비교하는게 s2가 아니라 s1인지도 이해가 안가네뇨.

아무튼 이 결과중 s3의 부분을 s2와 비교합니다. (S2.year = ( 부분)

그럼 그냥 

1990

1992

1993

1994

가 되는것 같은데...뭔가 야기서 크게 잘못 생각 하고 있다는 느낌이 듭니다...

이 쿼리가 실행되는 순서와 각 부분부분 대략 어던 데이커가 취득되는지 알고싶습니다 ㅠ 

 

by 겸댕2후니 [2015.06.11 10:18:48]

쿼리 의도가 이해가 가지 않네요...

lag, lead함수 검색해 보시는게 좋을 것 같아요.

그리고 위에 쓰신 말 중, 

-> 일단 실행순서는 가장 안쪽에있는 Max치를 검색하는 select문이 실행되고.

이는 실제 사실과 다른 것이, 서브쿼리 내에 메인쿼리 컬럼을 쓰고 있으므로

서브쿼리는 공급자 역할을 하지 못하고, 확인자 역할을 하게 됩니다...

따라서 서브쿼리가 먼저 읽히는게 아니라 메인쿼리가 읽힌 후에,

필터조건으로 확인자 역할을 하게 되겠죠.


by swlee710 [2015.06.11 10:27:18]

이런식으로 변경 가능합니다.

 

with sales (Year,sale) as (
select 1990, 50 from dual union all
select 1992, 50 from dual union all
select 1993, 52 from dual union all
select 1994, 55 from dual union all
select 1997, 55 from dual )
select year,sale
from (
Select year, sale,lag(sale) over(order by year) col
From sales)
where sale = col;


by 마농 [2015.06.11 10:46:38]

상관관계 서브쿼리 입니다.
메인쿼리의 컬럼이 서브쿼리에 조건으로 주어지는 형태죠.
메인쿼리가 실행되면서 매 행마다 서브쿼리가 실행되는 형태라고 보시면 됩니다.
메인쿼리의 첫번째 행의 연도(S1.year)보다 작은 연도(S3.year)중 최대값을 가져오구요
그 연도에 해당하는 금액(S2.sale) 가져옵니다.
그 금액이 메인의 해당 행의 금액(S1.sale)과 같은지 판단하는 거죠.


지금은 분석함수가 생기면서 이런식으로는 작성 잘 안합니다만....
작동 원리는 알아두시는 것이 좋습니다.
분석함수가 지원되지 않는 DB 라면 이런식으로 접근해야 합니다.


by 창조의날개 [2015.06.11 11:19:43]


위와 같은 경우 S1을 데이터 하나씩 조회 해온다고 생각하셔야 합니다.

1. S1에 1990, 50이 조회 됩니다.
   S3에서 S1의 1990보다 작은 S3가 없으므로 조회 되지 않습니다.

2. S1에 1992, 50이 조회 됩니다.
   S3에서 S1의 1992보다 작은 S3의 최대값은 1990입니다.
   S2의 SALE는 50이므로 1992,50이 조회 됩니다.

3. S1에 1993, 52이 조회 됩니다.
   S3에서 S1의 1993보다 작은 S3의 최대값은 1992입니다.
   S2의 SALE는 50이므로 S1의 52와 달라 조회 되지 않습니다.

이런 방식으로 마지막 로우까지 반복을 하게 됩니다.

결론적으로 이 쿼리는 이전년에서 SALE이 증가하지 못한 값을 조회 해오는 쿼리가 되겠네요..


by 김태성 [2015.06.11 15:20:51]

네분 다 정말 감사합니다. 겨우겨우 이해했네요 이해는 했는데 조금만 비틀어서 응용해보라 하면 또 틀릴 것 같습니다 ㅋ 그런 응용능력이랑 실행흐름을 이해하는게 지금 하는 공부의 목적인지라 ㅎ.ㅎ

마농님은 항상 답변해주시는데 정말 지식이 깊으시네요 ㅎㅎ

다 채택해 드리고 싶지만 결정적으로 알기쉽게 설명해주신 날개님 채택해 드릴개요 모두 감사합니다

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