Dav*_*veB 8 postgresql window-functions
我有一些表格可以跟踪运动员在赛道上的时间:
竞赛、竞赛用户和竞赛用户会话
我正在构建一个查询,用于提取每个提供的“competition_user”的当前排名和竞争对手总数,我可以得到排名,但是我的计数 (totalUsers) 没有计算竞争中的所有竞争对手,它似乎只是向上计数给提供的用户(例如,与排名相同)
SELECT compUserId, rank, totalUsers
FROM (
SELECT cu.competition_user_id as compUserId, cu.user_id as userId,
count(*) OVER w as totalUsers, rank() OVER w as rank
FROM competition_users cu
LEFT JOIN current_competition_sessions ccs ON cu.competition_user_id = ccs.competition_user_id
LEFT JOIN competition_user_sessions cus ON cus.competition_user_session_id = ccs.competition_user_session_id
WHERE cu.left_competition = false
AND cu.competition_id in (:compIds)
WINDOW w AS (PARTITION BY cu.competition_id ORDER BY cus.time_in_seconds ASC)
) as sub
WHERE compUserId in (:compUserIds)
Run Code Online (Sandbox Code Playgroud)
我的理解是默认框架是整个窗口,而这似乎是从框架开始到当前行计数?
Chr*_*ris 15
你出现问题是你申请的同一WINDOW(命名w为您的)COUNT(*)和你的rank()。
当您使用WINDOW包含ORDER BY子句的 a ,然后应用某些聚合(例如SUMor )时COUNT,它会在 ordering 中连续应用聚合,这就是为什么您的COUNTandrank()是相同的。
如果您修改您的查询有多个窗口作为
SELECT compUserId, rank, totalUsers
FROM (
SELECT cu.competition_user_id as compUserId, cu.user_id as userId,
count(*) OVER (PARTITION BY cu.competition_id) as totalUsers,
rank() OVER (PARTITION BY cu.competition_id ORDER BY cus.time_in_seconds ASC) as rank
FROM competition_users cu
LEFT JOIN current_competition_sessions ccs ON cu.competition_user_id = ccs.competition_user_id
LEFT JOIN competition_user_sessions cus ON cus.competition_user_session_id = ccs.competition_user_session_id
WHERE cu.left_competition = false
AND cu.competition_id in (:compIds)
) as sub
WHERE compUserId in (:compUserIds);
Run Code Online (Sandbox Code Playgroud)
以便您仅将PARTITION BY应用于您的COUNT(*)窗口,并且您的PARTITION BY和ORDER BY子句都具有rank(),我相信您会得到想要的结果。
参考这个SQL FIDDLE作为参考,我有一个通用id字段,一个com_num字段代表比赛id,一个com_time字段代表比赛时间。
| 归档时间: |
|
| 查看次数: |
14747 次 |
| 最近记录: |