计算与第一行中的值相同的后续行数

时间:2019-06-07 11:12:16

标签: sql count sql-server-2016

我有以下基本表:

+------------+--------+--------+--------+--------+
|    date    | CHFUSD | CHFJPY | CHFEUR | CHFGBP |
+------------+--------+--------+--------+--------+
| 24/03/2019 | 1.0016 | 0.009  | 1.1349 | 1.3327 |
| 23/03/2019 | 1.0016 | 0.009  | 1.1349 | 1.3327 |
| 22/03/2019 | 1.0016 | 0.009  | 1.1349 | 1.3209 |
| 21/03/2019 | 1.0016 | 0.0089 | 1.1349 | 1.3209 |
| 20/03/2019 | 1.0016 | 0.0089 | 1.1348 | 1.3209 |
| 19/03/2019 | 1.0016 | 0.0089 | 1.1348 | 1.3209 |
| 18/03/2019 | 0.998  | 0.0089 | 1.1359 | 1.3209 |
| 17/03/2019 | 1.0016 | 0.009  | 1.1349 | 1.3327 |
| 16/03/2019 | 1.0035 | 0.009  | 1.1348 | 1.3303 |
| 15/03/2019 | 0.998  | 0.0089 | 1.1359 | 1.3209 |
| 14/03/2019 | 0.998  | 0.0089 | 1.1359 | 1.3209 |
| 13/03/2019 | 0.998  | 0.0089 | 1.1359 | 1.3209 |
+------------+--------+--------+--------+--------+

这些是显示四个货币对的每日汇率的外汇汇率。我现在正在寻找一种方法来检查连续多少天交付的汇率相同。

查询的输出应如下所示:

+------------+--------+--------+--------+--------+
|    date    | CHFUSD | CHFJPY | CHFEUR | CHFGBP |
+------------+--------+--------+--------+--------+
| 24/03/2019 |      6 |      3 |      4 |      2 |
+------------+--------+--------+--------+--------+

如果日期会使练习复杂化,则它不是必需的列。有人对如何完成这项工作有想法吗?我在考虑一个窗口函数,该函数将值与先前的值进行比较,并根据该值返回0/1。然后是一个查询,该查询将对符合条件的行的值求和:date> =首个日期,值为0(每列)。

1 个答案:

答案 0 :(得分:2)

这是一个分组和孤岛查询-但由于要处理多个列而变得更加复杂。

我建议使用行号和日期的区别来定义组。然后是一个窗口函数来获取值:

select t.*,
       count(*) over (partition by chfusd, dateadd(day, - seqnum_chfusd, date)) as cnt_usd,
       count(*) over (partition by chfjpy, dateadd(day, - seqnum_chfjpy, date)) as cnt_jpy,
       count(*) over (partition by chfeur, dateadd(day, - seqnum_chfeur, date)) as cnt_eur,
       count(*) over (partition by chfgbp, dateadd(day, - seqnum_chgbp, date)) as cnt_gbp
from (select t.*,
             row_number() over (partition by chfusd order by date) as seqnum_chfusd,
             row_number() over (partition by chfjpy order by date) as seqnum_chfjpy,
             row_number() over (partition by chfeur order by date) as seqnum_chfeur,
             row_number() over (partition by chfgbp order by date) as seqnum_chfgbp
      from t
     ) t;

如果您要在最近的日期使用它,请添加select top (1)order by date desc。对于另一个日期,请使用子查询。