SQL 中的复杂排名 (Teradata)
Complex Ranking in SQL (Teradata)
我手头有一个特殊问题。我需要按以下方式排名:
- 每个 ID 都会获得一个新排名。
- 排名第一的是日期最短的 ID。但是,该特定 ID 的后续日期可能更高,但它们将获得增量排名 w.r.t 其他 ID。
(例如,ADF32 系列将被视为排名第一,因为它的日期最低,尽管它以日期 09-11 月结束,而 RT659 系列从 13-8 月开始,但排名随后)
- 对于一个特定的 ID,如果天数是连续的,那么排名相同,否则他们加 1。
- 对于特定 ID,排名按日期 ASC 给出。
如何制定查询?
在 lead/lag 上尝试 datediff,然后执行分区排序
select t.ID_COL,t.dt_col,
rank() over(partition by t.ID_COL, t.date_diff order by t.dt_col desc) as rankk
from ( SELECT ID_COL,dt_col,
DATEDIFF(day, Lag(dt_col, 1) OVER(ORDER BY dt_col),dt_col) as date_diff FROM table1 ) t
您需要两个步骤:
select
id_col
,dt_col
,dense_rank()
over (order by min_dt, id_col, dt_col - rnk) as part_col
from
(
select
id_col
,dt_col
,min(dt_col)
over (partition by id_col) as min_dt
,rank()
over (partition by id_col
order by dt_col) as rnk
from tab
) as dt
dt_col - rnk
计算连续日期相同的结果 -> 相同排名
思考这个问题的一种方法是“什么时候给等级加1”。好吧,当具有相同 id_col
的行上的前一个值相差超过一天时,就会发生这种情况。或者当该行是 id 的最早日期时。
这样就把问题变成了累加和:
select t.*,
sum(case when prev_dt_col = dt_col - 1 then 0 else 1
end) over
(order by min_dt_col, id_col, dt_col) as ranking
from (select t.*,
lag(dt_col) over (partition by id_col order by dt_col) as prev_dt_col,
min(dt_col) over (partition by id_col) as min_dt_col
from t
) t;
我手头有一个特殊问题。我需要按以下方式排名:
- 每个 ID 都会获得一个新排名。
- 排名第一的是日期最短的 ID。但是,该特定 ID 的后续日期可能更高,但它们将获得增量排名 w.r.t 其他 ID。 (例如,ADF32 系列将被视为排名第一,因为它的日期最低,尽管它以日期 09-11 月结束,而 RT659 系列从 13-8 月开始,但排名随后)
- 对于一个特定的 ID,如果天数是连续的,那么排名相同,否则他们加 1。
- 对于特定 ID,排名按日期 ASC 给出。
如何制定查询?
在 lead/lag 上尝试 datediff,然后执行分区排序
select t.ID_COL,t.dt_col,
rank() over(partition by t.ID_COL, t.date_diff order by t.dt_col desc) as rankk
from ( SELECT ID_COL,dt_col,
DATEDIFF(day, Lag(dt_col, 1) OVER(ORDER BY dt_col),dt_col) as date_diff FROM table1 ) t
您需要两个步骤:
select
id_col
,dt_col
,dense_rank()
over (order by min_dt, id_col, dt_col - rnk) as part_col
from
(
select
id_col
,dt_col
,min(dt_col)
over (partition by id_col) as min_dt
,rank()
over (partition by id_col
order by dt_col) as rnk
from tab
) as dt
dt_col - rnk
计算连续日期相同的结果 -> 相同排名
思考这个问题的一种方法是“什么时候给等级加1”。好吧,当具有相同 id_col
的行上的前一个值相差超过一天时,就会发生这种情况。或者当该行是 id 的最早日期时。
这样就把问题变成了累加和:
select t.*,
sum(case when prev_dt_col = dt_col - 1 then 0 else 1
end) over
(order by min_dt_col, id_col, dt_col) as ranking
from (select t.*,
lag(dt_col) over (partition by id_col order by dt_col) as prev_dt_col,
min(dt_col) over (partition by id_col) as min_dt_col
from t
) t;