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 服务器,那么您要考虑在您的选择子句中使用 TOP 3 和 ORDER BY PROFIT DESC。如果是 mysql/postgres,您可能还需要考虑在 select 子句中使用相同的 order by。

希望这可以帮助。

于 2012-01-10T16:21:58.130 回答