Roy*_*ish 3 sql-server sum dense-rank window-functions
我遇到以下情况,我很难理解如何申请DENSE_RANK()以获得我想要的结果:
| ID | 日期 | 价值 |
|---|---|---|
| 1 | 1990-05-17 | 1.00 |
| 1 | 1991-10-12 | 1.00 |
| 1 | 1992-08-01 | 1.00 |
| 1 | 1993-07-05 | 0.67 |
| 1 | 1994-05-02 | 0.67 |
| 1 | 1995-02-01 | 1.00 |
| 1 | 1996-03-01 | 1.00 |
根据上述数据,我尝试使用Date和Value列的组合来识别不同的时期,其中从列从一个值变为另一个值的位置来识别唯一的时期Value。这是我正在寻找的结果:
| ID | 日期 | 价值 | 时期 |
|---|---|---|---|
| 1 | 1990-05-17 | 1.00 | 1 |
| 1 | 1991-10-12 | 1.00 | 1 |
| 1 | 1992-08-01 | 1.00 | 1 |
| 1 | 1993-07-05 | 0.67 | 2 |
| 1 | 1994-05-02 | 0.67 | 2 |
| 1 | 1995-02-01 | 1.00 | 3 |
| 1 | 1996-03-01 | 1.00 | 3 |
正如您所看到的,有 3 个不同的时期。我遇到的问题是,当我使用 时DENSE_RANK(),我得到以下两个结果之一:
SELECT DENSE_RANK() OVER (PARTITION BY ID ORDER BY Date, Value)
| ID | 日期 | 价值 | 时期 |
|---|---|---|---|
| 1 | 1990-05-17 | 1.00 | 1 |
| 1 | 1991-10-12 | 1.00 | 2 |
| 1 | 1992-08-01 | 1.00 | 3 |
| 1 | 1993-07-05 | 0.67 | 4 |
| 1 | 1994-05-02 | 0.67 | 5 |
| 1 | 1995-02-01 | 1.00 | 6 |
| 1 | 1996-03-01 | 1.00 | 7 |
SELECT DENSE_RANK() OVER (PARTITION BY ID ORDER BY Value)
| ID | 日期 | 价值 | 时期 |
|---|---|---|---|
| 1 | 1990-05-17 | 1.00 | 1 |
| 1 | 1991-10-12 | 1.00 | 1 |
| 1 | 1992-08-01 | 1.00 | 1 |
| 1 | 1993-07-05 | 0.67 | 2 |
| 1 | 1994-05-02 | 0.67 | 2 |
| 1 | 1995-02-01 | 1.00 | 1 |
| 1 | 1996-03-01 | 1.00 | 1 |
正如您所看到的,问题出在该Date列上,因为我需要它是一个累积期间。此外,周期的长度会有所不同,ID并且ID该专栏背后没有一致的科学依据Date。例如,一名会员一年内可以有两次参赛资格。
您可以使用LAG()窗口函数获取每行的先前值,并使用SUM()窗口函数进行条件聚合,获取Periods:
SELECT ID, Date, Value,
SUM(CASE WHEN VALUE = prev_value THEN 0 ELSE 1 END) OVER (PARTITION BY ID ORDER BY Date) Period
FROM (
SELECT *, LAG(Value) OVER (PARTITION BY ID ORDER BY Date) prev_value
FROM tablename
) t
ORDER BY Date;
Run Code Online (Sandbox Code Playgroud)
请参阅演示。