SQL 查询以找出元素的最后一次出现

SQL query to find out the last but one occurance of an element

例如,我有这个 table:

seenID | personID | seenTime
-------+----------+---------
   108      3         13:34
   109      2         13:56
   110      3         14:22
   111      3         14:31
   112      4         15:04
   113      2         15:52
   114      3         15:55

我想获取 PersonID 最后一次出现的行。

所以所需的输出需要是(对于其中一个人 ID):

seenID | personID | seenTime
-------+----------+---------
   111      3         14:31

** 我正在使用此查询来获取第 n 次出现:

SELECT seenID,personID,seenTime FROM 
    (
        SELECT ROW_NUMBER() OVER(PARTITION BY personID ORDER BY personID) AS row_num,* 
        FROM "YourTableName"
    )AS T
WHERE row_num = 2

但要获得最后一次出现,我不知道 n 的值,并且 n 值对于不同的 personID 会有所不同。

您可以尝试使用 row_number()

with cte as
(
select seenid,personid,seentime,
  row_number() over(partition by personid order by seentime desc) as rn
from tablename
)

select * from cte where rn=1

您可以使用 min/max(或 min_by/max_by 如果需要)重载 which returns 具有 n 个最大值的数组并将其与 element_at(也许需要将其包装在 try() 中,但对于雅典娜风格的 presto 来说效果很好):

WITH dataset(seenID,personID,seenTime) AS (
   VALUES 
    (108,3,'13:34'),
    (109,2,'13:56'),
    (110,3,'14:22'),
    (111,3,'14:31'),
    (112,4,'15:04'),
    (113,2,'15:52'),
    (114,3,'15:55')
 ) 
 
SELECT personID, element_at(min(seenTime, 2), 2) second_from_start, element_at(max(seenTime, 2), 2) second_from_end
FROM dataset
group by personID

输出:

personID second_from_start second_from_end
3 14:22 14:31
2 15:52 13:56
4    

您走在正确的轨道上,但您想要 降序 order by。那样,你总是知道你想要第二个:

SELECT seenID, personID, seenTime 
FROM (SELECT ROW_NUMBER() OVER (PARTITION BY personID
                                ORDER BY personID DESC
--------------------------------------------------^
                               ) AS row_num,
             t.* 
      FROM "YourTableName" t
     ) AS T
WHERE row_num = 2