2012-01-10 9 views
3

은 행 내가 가장 효율적으로 (이익의) 가장 큰 행진에 참여하는 행을 선택 할 방법 행 수가 가장 많습니까?

symbol_id profit date 
1   100 2009-08-18 01:01:00 
1   100 2009-08-18 01:01:01 
1   156 2009-08-18 01:01:04 
1   -56 2009-08-18 01:01:06 
1   18  2009-08-18 01:01:07 

을 감안할 때.

가장 큰 줄무늬가 첫 번째 3 줄이 고 그 ​​줄이 필요할 것입니다. 필자가 생각해내는 쿼리는 중첩 쿼리 및 파생 테이블 일뿐입니다. 나는 일반적인 테이블 표현식이나 좀 더 진보 된 것을 사용하여 효율적인 방법을 찾고있다.

+2

? 순이익이 끝난 직후부터 높은 이익으로 끝나는 서열? – MatBailie

+0

네, 수익은 연속입니다. 부정적인 이익은 연속으로 끝납니다 – bladefist

답변

2

이익을 어떻게 처리해야하는지 또는 가장 긴 줄무늬가있는 경우 어떻게되는지 정의하지 않았습니다. 하지만 뭔가 같은 ...

;WITH T1 AS 
(
SELECT *, 
     ROW_NUMBER() OVER (PARTITION BY symbol_id ORDER BY date) - 
     ROW_NUMBER() OVER (PARTITION BY symbol_id, SIGN(profit) 
           ORDER BY date) AS Grp 
FROM Data  
), T2 AS 
(
SELECT *, 
     COUNT(*) OVER (PARTITION BY symbol_id,Grp) AS StreakLen 
FROM T1  
) 
SELECT TOP 1 WITH TIES * 
FROM T2 
ORDER BY StreakLen DESC 

또는 - 그 다음 MSSQL 서버의 경우에 당신은 당신이 당신의 선택 절 및 ORDER에서 TOP 3를 사용하는 것이 좋습니다 가장 수익성이 행진

;WITH T1 AS 
(
SELECT *, 
     ROW_NUMBER() OVER (PARTITION BY symbol_id ORDER BY date) - 
     ROW_NUMBER() OVER (PARTITION BY symbol_id, CASE WHEN profit >= 0 THEN 1 END 
           ORDER BY date) AS Grp 
FROM Data  
), T2 AS 
(
SELECT *, 
     SUM(profit) OVER (PARTITION BY symbol_id,Grp) AS StreakProfit 
FROM T1  
) 
SELECT TOP 1 WITH TIES * 
FROM T2 
ORDER BY StreakProfit DESC 
+0

'1,2,3,4,5,4,3,4,5,6'시퀀스가 '3,4,5,6 '로 나타났다. – MatBailie

+0

와우. 내 테이블의 11,618,019 개의 행과 쿼리가 즉시 실행됩니다. 너는 생명의 은인이야. 이제, 나는이 질의를 연구하고 그것으로부터 배워야 할 것입니다. – bladefist

0

를 찾고 있다면 이익 실현. mysql/postgres의 경우 select 절에서 limit를 사용하여 동일한 순서로 을 사용하는 것이 좋습니다.

희망이 도움이됩니다.

+0

관련이없는 다른 시점에 140의 이익을 가진 다른 기록이 있다면 어떨까요? 시퀀스는 수익 주문이 아닌 datetime 순서로 설정되어야합니다. – MatBailie

1
declare @T table 
(
    symbol_id int, 
    profit int, 
    [date] datetime 
) 

insert into @T values 
(1,   100, '2009-08-18 01:01:00'), 
(1,   100, '2009-08-18 01:01:01'), 
(1,   156, '2009-08-18 01:01:04'), 
(1,   -56, '2009-08-18 01:01:06'), 
(1,   18 , '2009-08-18 01:01:07') 

;with C1 as 
(
    select *, 
     row_number() over(order by [date]) as rn 
    from @T 
), 
C2 as 
(
    select *, 
     rn - row_number() over(order by rn) as grp 
    from C1 
    where profit >= 0 
) 
select top 1 with ties * 
from C2 
order by sum(profit) over(partition by grp) desc 

결과 :

`가장 큰 streak`을 정의 무엇
symbol_id profit  date     rn     grp 
----------- ----------- ----------------------- -------------------- -------------------- 
1   100   2009-08-18 01:01:00.000 1     0 
1   100   2009-08-18 01:01:01.000 2     0 
1   156   2009-08-18 01:01:04.000 3     0 
+0

응답 해 주셔서 감사합니다 – bladefist

관련 문제