我正在尝试根据条件生成一个数字。 当按 Start_Date 排序的 Client 分区中的“Stop”列中有 yes 时,Dense Rank 必须重新开始。所以我尝试了几件事,但它仍然不是我想要的。 我的表格有当前号码和预期号码
+-----------+------------+------+------------+-------------+
| Client_No | Start_Date | Stop | Current_No | Expected_No |
+-----------+------------+------+------------+-------------+
| 1 | 1-1-2018 | No | 1 | 1 |
+-----------+------------+------+------------+-------------+
| 1 | 1-2-2018 | No | 2 | 2 |
+-----------+------------+------+------------+-------------+
| 1 | 1-3-2018 | No | 3 | 3 |
+-----------+------------+------+------------+-------------+
| 1 | 1-4-2018 | Yes | 1 | 1 |
+-----------+------------+------+------------+-------------+
| 1 | 1-5-2018 | No | 4 | 2 |
+-----------+------------+------+------------+-------------+
| 1 | 1-6-2018 | No | 5 | 3 |
+-----------+------------+------+------------+-------------+
| 2 | 1-2-2018 | No | 1 | 1 |
+-----------+------------+------+------------+-------------+
| 2 | 1-3-2018 | No | 2 | 2 |
+-----------+------------+------+------------+-------------+
| 2 | 1-4-2018 | Yes | 1 | 1 |
+-----------+------------+------+------------+-------------+
| 2 | 1-5-2018 | No | 3 | 2 |
+-----------+------------+------+------------+-------------+
| 2 | 1-6-2018 | Yes | 2 | 1 |
+-----------+------------+------+------------+-------------+
到目前为止我使用的查询:
DENSE_RANK() OVER(PARTITION BY Client_No, Stop ORDER BY Start_Date ASC)
这似乎不是解决方案,因为它从值“否”算起,但我不知道如何用另一种方式处理这个问题。
最佳答案
解决此类 Gaps-And-Islands 难题的一种方法是首先计算以"is"停止的排名。
然后在该等级上计算 row_number 或 dense_rank。
例如:
create table test ( Id int identity(1,1) primary key, Client_No int, Start_Date date, Stop varchar(3) )
insert into test (Client_No, Start_Date, Stop) values (1,'2018-01-01','No') ,(1,'2018-02-01','No') ,(1,'2018-03-01','No') ,(1,'2018-04-01','Yes') ,(1,'2018-05-01','No') ,(1,'2018-06-01','No') ,(2,'2018-02-01','No') ,(2,'2018-03-01','No') ,(2,'2018-04-01','Yes') ,(2,'2018-05-01','No') ,(2,'2018-06-01','Yes')
select * , row_number() over (partition by Client_no, Rnk order by start_date) as rn from ( select * , sum(case when Stop = 'Yes' then 1 else 0 end) over (partition by Client_No order by start_date) rnk from test ) q order by Client_No, start_date GO
Id | Client_No | Start_Date | Stop | rnk | rn -: | --------: | :------------------ | :--- | --: | :- 1 | 1 | 01/01/2018 00:00:00 | No | 0 | 1 2 | 1 | 01/02/2018 00:00:00 | No | 0 | 2 3 | 1 | 01/03/2018 00:00:00 | No | 0 | 3 4 | 1 | 01/04/2018 00:00:00 | Yes | 1 | 1 5 | 1 | 01/05/2018 00:00:00 | No | 1 | 2 6 | 1 | 01/06/2018 00:00:00 | No | 1 | 3 7 | 2 | 01/02/2018 00:00:00 | No | 0 | 1 8 | 2 | 01/03/2018 00:00:00 | No | 0 | 2 9 | 2 | 01/04/2018 00:00:00 | Yes | 1 | 1 10 | 2 | 01/05/2018 00:00:00 | No | 1 | 2 11 | 2 | 01/06/2018 00:00:00 | Yes | 2 | 1
db<> fiddle here
使用这个的区别:
row_number() over (partition by Client_no, Rnk order by start_date)
与此相对:
dense_rank() over (partition by Client_no, Rnk order by start_date)
dense_rank 会为每个 Client_no 和 Rnk 的相同开始日期计算相同的数字。
关于sql - 基于条件的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59292274/