2

事前定義された一連のスキル評価を 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 ║
╚════════╩═══════════╩═══════╝

ここで、重み付けされたビジネス + ハッキングに従ってランク付けしたいと思います。

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;

それは私の推論の誤りによるものですか、不利なテーブル構造のためですか、それとも単にそれがそのままで、より良い代替手段がないためですか?

4

1 に答える 1