我需要对具有两列transID和travel_date的表进行排名
这是我的数据
transID travel_date
2341 2018-04-04 10:00:00
2341 2018-04-04 11:30:00
2891 2018-04-04 12:30:00
2891 2018-04-04 18:30:00
2341 2018-04-05 11:30:00
2891 2018-04-05 22:30:00
这是我尝试过的查询
select transID,travel_date,rn,
dense_rank () over (partition by transID order by EarliestDate,transID) as rn2
from
(SELECT transID,travel_date,
ROW_NUMBER() OVER (PARTITION BY transID ORDER BY travel_date) AS rn,
max(travel_date) OVER (partition by travel_date) as EarliestDate
FROM travel_log_info
) t
order by transID;
上述查询的当前输出
transID travel_date rn2
2341 2018-04-04 10:00:00 1
2341 2018-04-04 11:30:00 2
2341 2018-04-05 11:30:00 3
2891 2018-04-04 12:30:00 1
2891 2018-04-04 18:30:00 2
2891 2018-04-05 22:30:00 3
预期输出
transID travel_date rn2
2341 2018-04-04 10:00:00 1
2341 2018-04-04 11:30:00 2
2341 2018-04-05 11:30:00 1
2891 2018-04-04 12:30:00 1
2891 2018-04-04 18:30:00 2
2891 2018-04-05 22:30:00 1
使用此输出,我可以通过条件rn2 = 1来获得所需的输出,以基于旅行日期和transId获得输出。
如上所述,我没有得到所需的输出。请提供建议以实现正确的输出。 谢谢您的时间
答案 0 :(得分:3)
您现在拥有的主要问题是:
max(travel_date) OVER (partition by travel_date)
,其中包括分区中每个日期的时间部分-因此,您实际上获得的是每个单独日期/时间(即该日期/时间)的最大值。您似乎想要每天最多的日期/时间,因此可以通过在partition-by子句中使用trunc()
按每个天进行分区:
max(travel_date) OVER (partition by trunc(travel_date))
只要有了变化,您就可以:
TRANSID TRAVEL_DATE RN RN2
---------- ------------------- ---------- ----------
2341 2018-04-04 10:00:00 1 1
2341 2018-04-04 11:30:00 2 1
2341 2018-04-05 11:30:00 3 2
2891 2018-04-04 12:30:00 1 1
2891 2018-04-04 18:30:00 2 1
2891 2018-04-05 22:30:00 3 2
尽管外部查询中的分区也是错误的,但您需要按“最早”日期(实际上是最新的,但与此无关)进行分区:
select transID,travel_date,rn,
dense_rank () over (partition by transID,EarliestDate order by travel_date) as rn2
from
(SELECT transID,travel_date,
ROW_NUMBER() OVER (PARTITION BY transID ORDER BY travel_date) AS rn,
max(travel_date) OVER (partition by trunc(travel_date)) as EarliestDate
FROM travel_log_info
) t
order by transID;
TRANSID TRAVEL_DATE RN RN2
---------- ------------------- ---------- ----------
2341 2018-04-04 10:00:00 1 1
2341 2018-04-04 11:30:00 2 2
2341 2018-04-05 11:30:00 3 1
2891 2018-04-04 12:30:00 1 1
2891 2018-04-04 18:30:00 2 2
2891 2018-04-05 22:30:00 3 1
但是您实际上并不需要那个max或您当前拥有的外部查询;如果您在row_number()
分区(您当前尚未真正使用)中包含那截短的一天,则会得到:
SELECT transID,travel_date,
ROW_NUMBER() OVER (PARTITION BY transID, trunc(travel_date) ORDER BY travel_date) AS rn
FROM travel_log_info;
TRANSID TRAVEL_DATE RN
---------- ------------------- ----------
2341 2018-04-04 10:00:00 1
2341 2018-04-04 11:30:00 2
2341 2018-04-05 11:30:00 1
2891 2018-04-04 12:30:00 1
2891 2018-04-04 18:30:00 2
2891 2018-04-05 22:30:00 1
,然后可以将其包装在外部查询中以对rn
进行过滤:
SELECT transID,travel_date
FROM (
SELECT transID,travel_date,
ROW_NUMBER() OVER (PARTITION BY transID, trunc(travel_date) ORDER BY travel_date) AS rn
FROM travel_log_info
)
WHERE rn = 1
ORDER BY transID,travel_date;
TRANSID TRAVEL_DATE
---------- -------------------
2341 2018-04-04 10:00:00
2341 2018-04-05 11:30:00
2891 2018-04-04 12:30:00
2891 2018-04-05 22:30:00
您也可以不使用子查询来执行此操作;这将得到相同的结果using first
:
SELECT transID,
min(travel_date) keep (dense_rank first order by travel_date) as travel_date
FROM travel_log_info
GROUP BY transID, trunc(travel_date)
ORDER BY transID, travel_date;