프로그래밍
첫 페이지 회원가입 로그인
비공개 손님 2016-09-22 12:06:50
쿼리문 하나 질문 드립니다.

이게 소스로직이 아니라 쿼리로 가능한가 싶어서 질문드립니다.

하나의 차량ID에 2달치 데이터가 있다고 가정을 합니다.
(1달 30일로 가정하고 1~30일, 1~30일 해서 총 60건 있다고 가정)

여기서 날짜의 앞뒤 간격이 5일 이상 데이터가 없는 차량ID를 뽑아내야 하는데.

첫번째 차량을 봤을때

1일 데이터 O
2일 데이터 O
3일 데이터 X
4일 데이터 X
5일 데이터 X
6일 데이터 X
7일 데이터 X
8일 데이터 O

이 차량의 경우는 5일 이상 데이터가 안들어왔기 때문에 조건에 만족하는 차량 입니다.

두번째 차량을 봤을떄

1일 데이터 O
2일 데이터 X
3일 데이터 X
4일 데이터 X
5일 데이터 X
6일 데이터 O
7일 데이터 X
8일 데이터 X

이 차량의 경우는 데이터가 연속으로 들어오지 않은 날짜가 4일 이기 때문에 조건에 만족하지 않는 차량 입니다.

이 처럼 1번과 같은 경우. 최소 5일 이상 `연속적`으로 데이터가 들어오지 않은 차량 리스트를 뽑아야 하는데 이게 쿼리로 가능한가 싶어서 질문드려봅니다.

로직으로 날짜 루프를 돌려서 앞뒤 체크를 해야할거 같은데 이게 쿼리로 가능한가요?





질문 | 1104명이 읽었어요. 3.237.27.159 |

0
1 비공개 손님 2016-09-22 12:20:40
가능은 해보이는데..
아래 댓글님은 어떻게 생각하세요?
2 비공개 손님 2016-09-22 12:24:19
안되는게 어디있겠습니까?

답변은 아래 댓글님이 해주실거에요.
3 비공개 손님 2016-09-22 13:27:17
일단 차량 ID 목록을 테이블변수 or 임시테이블 (A, ID)로 하나 뽑아두시고
테이블변수(B) 하나 새로 지정하고
해당 ID들에 대해서 loop 돌려서
---각 ID에 대해서 날짜값 데이터 orderby해서 테이블에 넣고
---임시변수(diff) 하나 만들고 30 저장
---임시변수(pastdate)에 첫 날짜 저장
---첫행은 건너뛰고내부loop
------diff에 (pastdate - 현재행의 날짜값)과 diff의 현재 값 중 작은 값 저장
---diff가 5보다 크면 B에 ID, diff를 저장

최종적으로 B 출력
4 비공개 손님 2016-09-22 13:27:59
아, loop는 count(*)값이랑 변수 하나 지정해서 while 돌리면 돼여
5 비공개 손님 2016-09-22 13:31:24
3//답변 감사합니다. 말씀하신내용에 대해 소스적으로는 풀겠는데 이걸 쿼리문으로 짜려니 쪼끔 어렵네요 ㅡ_ㅜ 기본적인 쿼리문만 써봐서..=_=.. 한번 해봐야지요..
6 비공개 손님 2016-09-22 13:49:22
데이터 간격의 차를 SQL로 구해서 5보다 큰거 리스트만 뽑으면 나오지 않나여
7 비공개 손님 2016-09-22 15:20:20
존나 쉬운데요
8 비공개 손님 2016-09-22 15:25:04
걍 성능무시로

셀프조인 걸어서
on a.아이디 = b.아이디 and a.날짜 <= b.날짜
where b.날짜 - a.날짜 < 5

해서 나온 애들가지고 not in 으로 찾으면 되겠는데

중복은 존나 나올테니까 distinct를 하시던 뭘 하시던
9 비공개 손님 2016-09-22 19:04:59
8//죄송하지만 잘 이해가 되지 않는데 설명 좀 해주실수있으실까요 ㅡ_ㅜ?
말씀해주신거로 쿼리를 짜보곤 있는데 중복데이터 떄문인지 제대로 되지가 않네요 ㅜ_ㅜ
a.날짜 <= b.날짜는 왜 필요한건가용?
10 비공개 손님 2016-09-22 19:08:19
어 글니까 조인 걍 거는건데 엔바이엔 으로 걸기는 넘많을까바 걍 자기 빼고 날짜 큰 새끼들만 고르는건데 절케 바로 하면 안되겠네요 다시 생각해보니
11 비공개 손님 2016-09-22 19:11:17
그니까 요지는 자기랑 자기랑 날짜가 다른 자기랑 조인을 건담에 5일 안쪽에 들어오는 데이터가 있는 아이디를 뽑는건데요 생각해보니까 될것도 같은데
12 비공개 손님 2016-09-22 19:13:18
A라는애가 1일 3일 5일이 있을때 저렇게 조인 걸면
A 1 3
A 1 5
A 3 5

이렇게 데타가 나올텐데
13 비공개 손님 2016-09-22 19:17:04
계속 같은 얘기긴 한데 쿼리는 맞는거같구요 셀프 조인을 거는데 조건을 자기랑 자기보다 5일이내로 데이타가 존재하는 자기랑 조인을 건거에요 그럼 조건에 안만족하는 애들만 나오니까 낫인으로 다시 거르면 되는것
14 비공개 손님 2016-09-22 19:17:18
아 나 존나 친절해
15 비공개 손님 2016-09-22 19:19:03
아 부등호는 걍 < 네여
16 비공개 손님 2016-09-22 20:08:32
15//상세한 답변 감사합니다. 알려주신대로 돌려보았으나 문제가 날짜의 연속성을 체크하지 못합니다 ㅡ_ㅜ where b.날짜 - a.날짜 < 5 에서 차이가 5아래인 데이터만 조회하지만 b.날짜와 a.날짜에는 앞뒤간격이 아니라 n:n 으로 모든날짜를 체크하기 떄문에 힘들거같습니다
17 비공개 손님 2016-09-22 20:22:08
해결했습니다.
SELECT * FROM
(SELECT CAR_ID, MIN(SUM_DT) FROM_DT, MAX(SUM_DT) TO_DT, COUNT(*) CNT
FROM (SELECT * FROM RISK_DRIVE_SUM_V3 ORDER BY CAR_ID, SUM_DT)
GROUP BY CAR_ID, TO_CHAR(SUM_DT, 'yyyymmdd') - ROWNUM
ORDER BY CAR_ID, FROM_DT)
WHERE CNT >= 5
18 비공개 손님 2016-09-22 22:30:13
음 걍 각 날짜별로 5일 이내 데이터만 확인하면 되는거 같은데 어쨌든 하셨다니 다행
19 비공개 손님 2016-09-22 23:05:33
걍 카운트만 세면 되는데
20 비공개 손님 2016-09-23 00:55:09
오라클 디스턴스로 구하면 짱빠름...
21 비공개 손님 2016-09-23 09:10:28
아항 그러네
a.ROW_NUM == b.ROW_NUM+1로 셀프조인 때리고선
날짜 차이 5 이상 나는 거 찾는 방법이 있었구나

22 비공개 손님 2016-09-23 17:43:22
왠만하면 데이터구문에 로직넣는 이른바 metaprogramming 은 하지마세요

유지보수하게 개힘들어집니다
23 비공개 손님 2016-09-23 17:45:24
data domain 이랑 상관없는 util성 store procedure 같은거는 dba 한테 맡기는게 좋아요 그런건 그사람들이 전문가니깐..

SQL에 로직 들어가기 시작하면 언젠가 나중에 관련 비즈니스 로직 수정을 못따라가는 순간이 발생할 것이며 진정한 디버깅의 비극은 그때 시작될겁니다. 스키마 변경이라던가, 레코드 추출조건이 바뀐다던가... 등등.
24 비공개 손님 2016-09-27 11:38:34
아 저 해당 쿼리는 단발성 쿼리 입니다 ㅎ DBA가 없어서 ㅡ_ㅜ
댓글을 작성하실 수 없습니다.
(권한이 없는 회원레벨)
목록으로
이용약관 | 광고/제휴 | 개인정보취급방침 | 문의/신고 | 모바일 TE31 | 서버 부하 : 15.25%
실시간 Issue 커뮤니티 TE31 [알지롱] ⓒ 2002-2021
TOP arrow_upward