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