2013-04-22 42 views
2

我需要從PostgreSQL表中查詢預定義的技能等級集。考慮與用戶1,2和3,各自有不同的技能和技能等級下面的演示表:技能SQL查詢表

╔════════╦═══════════╦═══════╗ 
║ 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 ║ 
╚════════╩═══════════╩═══════╝ 

現在我想根據加權商業+黑客來對他們進行排名:

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做更多的計算不是必要的,因爲錯綜複雜的辦案WHE重新使用者不會有黑客行爲,但可以使用商業技能或其他方式。如果沒有這種情況下(即商務和黑客技術都需要進入排名)查詢可能是一個更容易:

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; 

難道是因爲我的推理錯誤,一個不利的表結構或只是因爲這是它的方式,沒有更好的選擇?

回答

2

您可以用聚合查詢做到這一點:

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 desc 
+0

非常感謝,這個工程就像一個魅力。好的解決方案我假設你是一位數據庫專家:你對技能數據存儲方式有何看法?你會做不同的事情嗎? – ideaboxer 2013-04-22 01:28:57