_대문 | 방명록 | 최근글 | 홈피소개 | 주인놈
FrontPage › 3연속승리

Contents

[-]
1 방법1
2 방법2
3 방법3


한개의 id가 시간의 순서에 따라서 3번 연속으로 승리한 시간을 뽑고자 하는 경우다. 직장의 후배놈이 물어봐서 예제를 만들어봤다. 알려줘야 하는데 계속 까먹는다.

1 방법1 #

drop table #temp 
create table #temp(id varchar(20), win bit, dt datetime default getdate())
insert #temp(id, win) values ('a', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('a', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('a', 0) waitfor delay '00:00:01'
insert #temp(id, win) values ('a', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('a', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('a', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 0) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 0) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 1) waitfor delay '00:00:01'
--insert #temp(id, win) values ('b', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 0) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 1) waitfor delay '00:00:01'
insert #temp(id, win) values ('b', 1)

;with temp
as
(
	select * , row_number() over(partition by id order by dt) rownum
	from #temp
), rs1
as
(
	select --*
		a.id
	,	a.rownum
	,	max(b.rownum) max_rownum
	,	max(b.dt) max_dt
	,	isnull(count(case when b.win = 1 and a.rownum-b.rownum <> 1 then 1 end),0) cnt
	,	isnull(min(case when a.rownum-b.rownum = 1 then convert(int,b.win) end),0) prev1_row
	from temp a inner join temp b
	on a.id = b.id
	and a.rownum in (b.rownum+1, b.rownum, b.rownum-1, b.rownum-2)
	group by
		a.id
	,	a.rownum
	having isnull(count(case when b.win = 1 and a.rownum-b.rownum <> 1 then 1 end),0) = 3
), rs2
as
(
	select *, row_number() over(partition by id order by rownum) rownum2
	from rs1	
)
select * 
from rs2
where prev1_row = 0 or rownum2 % 3 = 1
order by id, rownum

2 방법2 #

이전 Row 접근하기 를 참고하여 cross join을 하면 된다.
4번째 이전 row가 1이 아니고, 3번째 2번째 그리고 현재 row가 승리이면 3연속이다.

3 방법3 #

sql말고 다른 방법으로 처리한다.
ssis와 같은 row 기반 처리하는 솔루션을 이용한다.
이와 같은 문제는 sql이 어울리지 않는다.

댓글 남기기..
이름: : 오른쪽의 새로고침을 클릭해 주세요. 새로고침
EditText : Print : Mobile : FindPage : DeletePage : LikePages : Powered by MoniWiki : Last modified 2018-04-13 23:12:52

청년이여! 그대의 머리로 사색하고 그대의 손으로 탐구하고 그대의 발로 서라.