sql - Oracle SQL 条件排序
问题描述
在我的查询中,我正在执行多种类型的排名,对于其中一种排名类型,我只想在某些列不为空时才对行进行排名。否则我不希望排名发生。
例如,这是一个示例表:
+------+------------+------------+--------+--------+
| col1 | col2 | col3 | rank 1 | rank 2 |
+------+------------+------------+--------+--------+
| a | 2018-01-20 | 2018-03-04 | 2 | 2 |
| a | 2018-01-24 | 2018-04-04 | 1 | 1 |
| b | 2018-01-02 | 2018-05-03 | 1 | 1 |
| c | 2017-01-02 | 2017-05-08 | 3 | 2 |
| d | 2016-05-24 | null | 1 | null |
| c | 2018-02-05 | 2018-05-03 | 2 | 1 |
| c | 2018-07-28 | null | 1 | null |
+------+------------+------------+--------+--------+
rank1 可以根据partition by col1 order by col2 desc
rank 计算 2 应该以相同的方式计算,但只有当 col3 为 null 时,否则它应该为 null。
如何在单个查询中实现两个排名?我尝试对rank2使用case语句,但是当col3为null时它会跳过排名,
解决方案
如果我理解正确,您可以尝试使用CASE WHEN
窗口sum
功能
CASE WHEN
检查col3
不null
累积否则显示NULL
CREATE TABLE T(
col1 VARCHAR(5),
col2 DATE,
col3 DATE
);
INSERT INTO T VALUES ( 'a' , to_date('2018-01-20','YYYY-MM-DD') , to_date('2018-03-04','YYYY-MM-DD'));
INSERT INTO T VALUES ( 'a' , to_date('2018-01-24','YYYY-MM-DD') , to_date('2018-04-04','YYYY-MM-DD'));
INSERT INTO T VALUES ( 'b' , to_date('2018-01-02','YYYY-MM-DD') , to_date('2018-05-03','YYYY-MM-DD'));
INSERT INTO T VALUES ( 'c' , to_date('2017-01-02','YYYY-MM-DD') , to_date('2017-05-08','YYYY-MM-DD'));
INSERT INTO T VALUES ( 'd' , TO_DATE('2016-05-24','YYYY-MM-DD') , null);
INSERT INTO T VALUES ( 'c' , TO_DATE('2018-02-05','YYYY-MM-DD') , to_date('2018-05-03','YYYY-MM-DD'));
INSERT INTO T VALUES ( 'c' , TO_DATE('2018-07-28','YYYY-MM-DD') , null);
查询 1:
select t1.*,
rank() OVER(partition by col1 order by col2 desc) rank1,
(CASE WHEN COL3 IS NOT NULL THEN
SUM(CASE WHEN COL3 IS NOT NULL THEN 1 ELSE 0 END) OVER(partition by col1 order by col2 desc)
ELSE
NULL
END) rank2
FROM T t1
结果:
| COL1 | COL2 | COL3 | RANK1 | RANK2 |
|------|----------------------|----------------------|-------|--------|
| a | 2018-01-24T00:00:00Z | 2018-04-04T00:00:00Z | 1 | 1 |
| a | 2018-01-20T00:00:00Z | 2018-03-04T00:00:00Z | 2 | 2 |
| b | 2018-01-02T00:00:00Z | 2018-05-03T00:00:00Z | 1 | 1 |
| c | 2018-07-28T00:00:00Z | (null) | 1 | (null) |
| c | 2018-02-05T00:00:00Z | 2018-05-03T00:00:00Z | 2 | 1 |
| c | 2017-01-02T00:00:00Z | 2017-05-08T00:00:00Z | 3 | 2 |
| d | 2016-05-24T00:00:00Z | (null) | 1 | (null) |
推荐阅读
- p5.js - 如何使用 p5.js /p5.play 让所有精灵移动到不同的吸引力点
- r - 使用 scale_x_datetime() 设置限制会在 ggplot 中静默放置条形图
- java - spring cloud stream - StreamBridge - 当远程目的地没有人消费消息时,消息不会进入DLQ
- c++ - 使用标记值和计数器控制从文件中获取数据
- node.js - 在 Flutter 中显示 JSON 数据
- c++ - 无法使用 lambda 初始化模板 constexpr 成员变量
- .net - 在 Refit Proxy 和 DelegatingHandler 之间传递值
- javascript - 仅当数组值与对象数组键匹配时如何获取对象数组
- sql - 为什么 postgres 查询需要这么长时间
- cypress - 以下错误源于您的测试代码,而不是赛普拉斯 - 未定义进程