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 行であり、それらの行が必要です。私が思いついたクエリは、ネストされたクエリと派生テーブルの集まりです。一般的なテーブル式またはより高度なものを使用してこれを行う効率的な方法を探しています。

4

3 に答える 3

2

0利益をどのように扱うべきか、または最長連勝が同点の場合にどうなるかを定義していません。しかし、何か...

;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

または - 最も収益性の高いストリークを探している場合

;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
于 2012-01-10T16:17:20.533 に答える
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

結果:

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
于 2012-01-10T16:25:51.770 に答える
0

それが MSSQL サーバーの場合は、SELECT 句で TOP 3 を使用し、ORDER BY PROFIT DESC を使用することを検討してください。mysql/postgres の場合、select 句で limit を同じ order by で使用することを検討することもできます。

お役に立てれば。

于 2012-01-10T16:21:58.130 に答える