1

私は SQL Server 2008 でトリガーに取り組んだことがありません。そのため、その方法がわかりません。

私はゲーム アプリケーションを持っており、プレイした質問の数と正解した質問の総数を追跡しています。また、各質問の平均所要時間も記録しています。

ここで、正答率に応じてランクを記録したいと思います。同点の場合は、所要時間を確認します。これらすべてをトリガーを使用して行う必要があります。

  id   | playerID | CompetitionID  | NoOfCOrrectANswers | NoOfPlayedQuestions | TimeTaken 
-----------------------------------------------------------------------------------------
  1      3             203              4                       8                  8.4
  2      56            203              9                      18                 13
  3      67            203              16                     45                 15

どんな助けでも大歓迎です。前もって感謝します。

4

1 に答える 1

2

更新の数が多くなるため、おそらくこの道を進むべきではありません。競争の結果を提示するクエリにrow_number()またはrank()関数を追加することができます。

そうは言っても、絶対にランキング情報をテーブルに保持する必要があると思われる場合は、列を追加してください

alter table ATable add PlayerRank int

ATableでトリガーを作成します

create trigger RankingTrigger on ATable
after insert, update, delete
as
-- We don't want queries in a trigger to mess up with "Rows affected"
   set nocount on
-- If any of the following columns are mentioned in a query
-- Always true for insert and delete, but we will save updates
-- if we skip processing when columns participating in ranking 
-- are not changed
   If update (NoOfCOrrectANswers)
      OR update(NoOfPlayedQuestions)
      OR update(TimeTaken)
   begin
      -- CTE that returns primary key and rank by competition.
      -- I've changed your condition (percent of correct answers)
      -- As it would rank players with one correct answer over those
      -- who answered 100 questions and got only one wrong. If you
      -- want to change it, replace NoOfCOrrectANswers with 
      -- NoOfCOrrectANswers / NoOfPlayedQuestions
      ; with theRank as (
        select ID, row_number() over (partition by CompetitionID
                                      order by NoOfCOrrectANswers DESC,
                                               TimeTaken DESC) rn
          from ATable
      -- Only changed competitions
         where CompetitionID in
      -- Inserted table is available in trigger and OUTPUT clause
      -- of insert, update, delete statements.
      -- It contains newly added/changed rows
      -- We are using it here to filter only changed competitions
      -- Similary, Deleted table hold a copy of removed rows for delete 
      -- and old values for update
         (
            select CompetitionID
              from Inserted
            union
            select CompetitionID
              from Deleted
         )
      )
      update ATable
      -- Update to rank from theRank CTE
         set PlayerRank = theRank.rn
        from ATable
        -- All records participation in affected competitions
          inner join theRank
             on ATable.ID = theRank.ID
        -- Only change if really changed
        -- This part is very likely not needed. I have never tested
        -- to see if it affects performance
            and isnull(ATable.PlayerRank, 0) <> theRank.rn
   end
于 2012-04-10T13:54:47.123 に答える