我有如下示例数据:用户名活动开始时间结束时间AceDancing13:0014:00 AceSinging15:0016:30 AceYoga19:0020:00 AlicePiano10:0011:00 AliceHiking14:0015:00 A...
我有如下示例数据:
用户名 | 活动 | 开始时间 | 结束时间 |
---|---|---|---|
高手 | 跳舞 | 13:00 | 14:00 |
高手 | 歌唱 | 15:00 | 16:30 |
高手 | 瑜伽 | 19:00 | 20:00 |
爱丽丝 | 钢琴 | 10:00 | 11:00 |
爱丽丝 | 远足 | 14:00 | 15:00 |
爱丽丝 | 阅读 | 16:00 | 16:30 |
爱丽丝 | 游泳 | 19:00 | 20:00 |
爱丽丝 | 写作 | 21:00 | 21:30 |
狮子 | 钓鱼 | 13:00 | 17:00 |
我想找到每个用户的倒数第二个活动, 如果只记录一个活动,则输出该活动 ,也就是说,我希望得到以下输出:
用户名 | 倒数第二幕 |
---|---|
高手 | 歌唱 |
爱丽丝 | 游泳 |
狮子 | 钓鱼 |
我尝试过但无法获得 Lion
:
SELECT username, activity AS penultimate_act
FROM (
SELECT
username,
activity,
DENSE_RANK() OVER (PARTITION BY username ORDER BY starttime DESC) AS seq
FROM activities
) t
WHERE seq = 2;
然后我再次尝试:
SELECT username, activity AS penultimate_act
FROM (
SELECT
username,
activity,
DENSE_RANK() OVER (PARTITION BY username ORDER BY starttime DESC) AS seq
FROM activities
) t
WHERE seq = 2 or seq = 1;
但它仍然不能完全满足我的需求,有人可以提供一些帮助吗?(如果您没有听说过我的数据库,您可以使用 PostgreSQL 来演示。谢谢!)
我会保留您已有的查询,然后添加第二个查询来获取仅出现一次的用户名及其活动。您可以将这两个查询合并为 UNION ALL
.
使用 GROUP BY
with 子句 HAVING
仅选择仅出现一次的用户名:
-- your existing query...
UNION ALL
SELECT username, MAX(activity)
FROM activities
GROUP BY username
HAVING COUNT(*) = 1;
比 ROW_NUMBER
在查询中 DENSE_RANK
使用更快
两者都将为您的样本数据产生预期的结果:
用户名 | 倒数第二幕 |
---|---|
高手 | 歌唱 |
爱丽丝 | 游泳 |
狮子 | 钓鱼 |
查看 演示 .