Oracle SQL条件排名
在我的查询中,我正在进行多种类型的排序,对于其中一种排序类型,我只想在某个列不为空时对行进行排序。否则我就不想排名了 例如,下面是一个示例表:Oracle SQL条件排名,sql,oracle,ranking,rank,Sql,Oracle,Ranking,Rank,在我的查询中,我正在进行多种类型的排序,对于其中一种排序类型,我只想在某个列不为空时对行进行排序。否则我就不想排名了 例如,下面是一个示例表: +------+------------+------------+--------+--------+ | col1 | col2 | col3 | rank 1 | rank 2 | +------+------------+------------+--------+--------+ | a | 2018-01-20
+------+------------+------------+--------+--------+
| 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是基于按col2 desc按col1顺序划分的计算得出的
秩2的计算方法应相同,但仅当col3为null时,否则应为null
如何在一个查询中实现两个级别?我尝试使用rank2的case语句,但当col3为null时,它会跳过排名,我想您可能需要:
select count(col3) over (partition by col1 order by col2 desc)
请注意,这相当于行号()
,而不是rank()
。对于您的数据,这些是等效的。如果我理解正确,您可以尝试使用CASE WHEN
和sum
窗口函数
检查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) |
:
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) |
如果col3
为null
我希望根据col2日期计算排名,但仅当第3列不为null时。如果第3列为空,则不应计算秩,因此应为空。好的,您可以尝试我的答案:)@Sejal parikh这确实有效!你能解释一下这背后的逻辑吗?我想了解你是如何想到在这里使用sum而不是rank的。要检查col3
是否为NULL
如果col3
为NULL
则进行累加,否则只显示NULL
没有做任何事情。我会在时使用sum
而不是rank
,因为if当col3为null