我需要从PostgreSQL表中查询预定义的技能评级集。考虑以下用户1、2和3的演示表,每个用户都有不同的技能和技能评级:
╔════════╦═══════════╦═══════╗
║ userId ║ skillId ║ votes ║
╠════════╬═══════════╬═══════╣
║ 1 ║ marketing ║ 50 ║
║ 2 ║ hacking ║ 51 ║
║ 1 ║ business ║ 59 ║
║ 2 ║ business ║ 8 ║
║ 1 ║ hacking ║ 32 ║
║ 3 ║ talking ║ 67 ║
║ 3 ║ business ║ 34 ║
║ 3 ║ marketing ║ 24 ║
╚════════╩═══════════╩═══════╝现在我想根据加权business+hacking对它们进行排名:
SELECT * FROM
(SELECT
b."userId",
MAX(CASE WHEN b."skillId"='business' THEN b.votes ELSE 0 END) AS "businessVotes",
MAX(CASE WHEN h."skillId"='hacking' THEN h.votes ELSE 0 END) AS "hackingVotes"
FROM "Skill" b, "Skill" h
WHERE b."userId"=h."userId"
AND (
(b."skillId"='business' AND h."skillId"='hacking') OR
(b."skillId"=h."skillId" AND (b."skillId"='business' OR b."skillId"='hacking'))
)
GROUP BY b."userId") AS query
ORDER BY "businessVotes"*0.2+"hackingVotes"*0.8 DESC不出所料,我得到了以下结果:
╔════════╦═══════════════╦══════════════╗
║ userId ║ businessVotes ║ hackingVotes ║
╠════════╬═══════════════╬══════════════╣
║ 2 ║ 8 ║ 51 ║
║ 1 ║ 59 ║ 32 ║
║ 3 ║ 34 ║ 0 ║
╚════════╩═══════════════╩══════════════╝但在我看来,这个查询需要PostgreSQL做更多的计算,因为它复杂地处理用户没有黑客技能而是商业技能的情况,或者反过来。如果没有这种情况(即需要业务和黑客技能才能进入排名),查询可能会容易得多:
SELECT *
FROM "Skill" t1, "Skill" t2
WHERE t1."userId"=t2."userId"
AND (t1."skillId"='business'
AND t2."skillId"='hacking')
ORDER BY t1."votes"*0.2 + t2."votes"*0.8 DESC;是因为我推理中的错误,一个不利的表结构,还是因为它就是这样的,没有更好的替代方案?
发布于 2013-04-22 09:23:23
您可以使用聚合查询来执行此操作:
select s.userId,
sum((case when s.skillId = 'business' then votes else 0 end)*0.2 +
(case when s.skillId = 'hacking' then votes else 0 end)*0.8
) as weightedpoints
from skill s
group by userId
order by weightedpoints deschttps://stackoverflow.com/questions/16138034
复制相似问题