sql - 将连续的 "Wins"分组为一行

标签 sql mysql

给定行:

symbol_id profit date
1         100    2009-08-18 01:01:00
1         100    2009-08-18 01:01:01
2         80     2009-08-18 01:01:02
2         -10    2009-08-18 01:01:03
1         156    2009-08-18 01:01:04
2         98     2009-08-18 01:01:05
1         -56    2009-08-18 01:01:06
1         18     2009-08-18 01:01:07
3         234    2009-08-18 01:01:08
3         167    2009-08-18 01:01:09
3         34     2009-08-18 01:01:10

我正在寻找每个symbol_id的平均和最大盈利/连胜(利润 >= 0)和亏损(利润 < 0)。

仅查看 symbol_id = 1:

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 场胜利 ((3 + 1)/2)
最大连胜数为 3
平均 1 次损失 (1/1)
最大的条纹是 1

期望的查询结果:

symbol_id avg_winning_streak largest_winning avg_losing_streak largest_losing_streak
1         2                  3               1                 1
2         1                  1               1                 1
3         3                  3               0                 0

最佳答案

我为 SQL Server 2005 或更高版本编写了一个解决方案。这是标准的SQL,但我不知道MySQL是否支持row_number()。如果需要,您可以用子查询替换 CTE。

请注意,我将零利润视为盈利和亏损,这只是处理零的一种方式。您可以更改这两行中的不等式以不同方式计算零:

case when sp>=0 then 1.0*count(*) end as win_run_len_decimal,
case when sp<=0 then 1.0*count(*) end as loss_run_len_decimal

这是完整的查询:

with Trk as (
  select
    symbol_id,
    sign(profit) as sp,
    row_number() over (
      partition by symbol_id
      order by d
    ) as rk,
    row_number() over (
      partition by symbol_id,sign(profit)
      order by d
    ) as rksp
  from T
), Trk_agg as (
  select
    symbol_id,
    sp,
    case when sp>=0 then 1.0*count(*) end as win_run_len_decimal,
    case when sp<=0 then 1.0*count(*) end as loss_run_len_decimal
  from Trk
  group by symbol_id, sp, rk-rksp
)
  select
    symbol_id,
    avg(win_run_len_decimal) as avg_winning_streak,
    max(win_run_len_decimal) as longest_winning_streak,
    avg(loss_run_len_decimal) as avg_losing_streak,
    max(loss_run_len_decimal) as longest_losing_streak
  from Trk_agg
  group by symbol_id;

关于sql - 将连续的 "Wins"分组为一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1292221/

相关文章:

MySQL 用联合选择层次结构

java - org.h2.jdbc.JdbcSQLException : Table "PACCHETTIVISITETURISTICHE" not found; SQL statement:

mysql - 令人难以置信的 SQL 困境

php - 错误: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined NOOB

mysql - 为什么我们必须在插入数据库之前解析日期?

mysql - 我的查询需要哪种连接类型

mysql - 获取值上方和下方的行或最近的行

php - mysql_fetch_assoc 查询中的 COUNT、IF

php - 从登录 session 中获取 ID 并填充到主页 : php and mysql

javascript - Sequelize,在不提交事务的情况下在插入后立即读取插入行的 id