sql - 数量基于条件
问题描述
我正在尝试根据条件生成一个数字。当按 Start_Date 排序的客户端分区中的“停止”列中为“是”时,密集排名必须重新开始。所以我尝试了几件事,但这仍然不是我想要的。我的表有当前号码和预期号码
+-----------+------------+------+------------+-------------+
| 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)
这似乎不是解决方案,因为它从值“否”开始计算,但我不知道如何以另一种方式处理这个问题。
解决方案
解决这种“差距与岛屿”难题的一种方法是首先计算一个以“是”止损开头的排名。
然后在该排名上计算 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
身份证 | 客户_否 | 开始日期 | 停止 | rnk | rn -: | --------: | :----------------- | :--- | --: | :- 1 | 1 | 01/01/2018 00:00:00 | 没有 | 0 | 1 2 | 1 | 01/02/2018 00:00:00 | 没有 | 0 | 2 3 | 1 | 2018 年 1 月 3 日 00:00:00 | 没有 | 0 | 3 4 | 1 | 01/04/2018 00:00:00 | 是 | 1 | 1 5 | 1 | 01/05/2018 00:00:00 | 没有 | 1 | 2 6 | 1 | 2018 年 1 月 6 日 00:00:00 | 没有 | 1 | 3 7 | 2 | 01/02/2018 00:00:00 | 没有 | 0 | 1 8 | 2 | 2018 年 1 月 3 日 00:00:00 | 没有 | 0 | 2 9 | 2 | 01/04/2018 00:00:00 | 是 | 1 | 1 10 | 2 | 01/05/2018 00:00:00 | 没有 | 1 | 2 11 | 2 | 2018 年 1 月 6 日 00:00:00 | 是 | 2 | 1
db<>在这里摆弄
使用这个的区别:
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 计算相同的start_date 数字。
推荐阅读
- c++ - malloc 在 C++17 中是否返回“无效指针值”?
- javascript - 如何使用电子的相对路径从 html 显示本地图像?
- javascript - 将 promise 组合成 promise.all
- reactjs - React hooks:我在做一个反模式吗?更新组件外函数中的状态
- azure - 在两个区域上启用读取和写入的 AZURE COSMOS DB,我们可以在两个区域上运行 ADF 管道吗?
- r - `sheets_auth`(来自 `googlesheets4`)不适用于使用 `googleAuthR` 包创建的令牌
- php - 在php中将数组转换为xml
- excel - 使用Word文档中的句子引用提取页码
- node.js - 如何将 node_modules 文件夹添加到现有的角度文件?
- ios - 如何使用 Flutter 在 iOS 中测试验证 InAppPurchase