2

投票結果を取得するためのクエリを作成しようとしています。

誰かが行ったすべての投票を記録する表があります。人々が複数回投票することは可能ですが、最後の投票のみを考慮に入れる必要があります。

「ユーザーの最後の投票のみを考慮に入れる必要がある」部分を除いて、私はそれが機能する時点にいます。

これは私のテーブルです:

テーブル投票:

  id            bigint      PK
  TimeStamp     datetime
  QuestionId    int
  UserId        int

およびLinqクエリ:

var total = (float)(_db.Votes).Count(vote => vote.Timestamp>=startWeekDay && vote.Timestamp<endWeekDay);

var results = (from vote in _db.Votes 
                  where vote.Timestamp >= startWeekDay && vote.Timestamp < endWeekDay
                  group vote by new { vote.QuestionId} into g
                  orderby g.Count() descending
                  select new VoteResults()
                      {
                          QuestionID = g.Key.QuestionId, 
                          Percentage = (g.Count() / total * 100.0f),
                      }).ToList();

私の質問:ユーザーごとの最後の決定票のみが考慮されるように、このクエリを変更するにはどうすればよいですか?

編集:この入力を考えると:

{
    UserId = 1,
    QuestionId = 2,
    TimeStamp = Yesterday
},
{
    UserId = 1,
    QuestionId = 1,
    TimeStamp = Today
},
{
    UserId = 2,
    QuestionId = 2,
    TimeStamp = Yesterday
},
{
    UserId = 3,
    QuestionId = 1,
    TimeStamp = Yesterday
}

出力は次のようになります。

{
    QuestionID = 2,
    Percentage = 33.3333
},
{
    QuestionID = 1,
    Percentage = 66.66666
}
4

1 に答える 1

2

以下に、コンソールアプリで実行したテストケースを示します...問題が解決するはずです。例で渡したデータを使用してテストしました。

public class User
{
    public int UserId {get; set;}
}

public class Question
{
    public int QuestionId { get; set; }
}

public class Vote
{
    public int VoteId {get; set;}
    public DateTime TimeStamp {get; set;}
    public Question Question {get; set;}
    public User User { get; set; }
}

public class VoteResult
{
    public int QuestionId { get; set; }
    public float Percentage { get; set; }
}

public class Program
{
    static void Main(string[] args)
    {
        var question1 = new Question();
        question1.QuestionId = 1;

        var question2 = new Question();
        question2.QuestionId = 2;

        var user1 = new User();
        user1.UserId = 1;

        var user2 = new User();
        user2.UserId = 2;

        var user3 = new User();
        user3.UserId = 3;

        List<Vote> votes = new List<Vote>()
        {
            new Vote()
            { 
                Question = question2,
                TimeStamp = DateTime.Today.AddDays(-1), // Yesterday
                User = user1,
                VoteId = 1
            },

            new Vote()
            { 
                Question = question1,
                TimeStamp = DateTime.Today,
                User = user1,
                VoteId = 2
            },

            new Vote()
            {
                Question = question2,
                TimeStamp = DateTime.Today.AddDays(-1), // Yesterday
                User = user2,
                VoteId = 3
            },

            new Vote()
            {
                Question = question1,
                TimeStamp = DateTime.Today.AddDays(-1), // Yesterday
                User = user3,
                VoteId = 4
            }
        };

        // Group Votes by User and then Select only the most recent Vote of
        // each User
        var results = from vote in votes
                        where vote.TimeStamp >= DateTime.Today.AddDays(-7) &&
                              vote.TimeStamp < DateTime.Today.AddDays(1)
                        group vote by vote.User into g
                        select g.OrderByDescending(v => v.TimeStamp).First();

        // Total Users who voted
        var total = results.Count();

                               // Group Users' votes by Question
        foreach (var result in results.GroupBy(v => v.Question.QuestionId))
        {
            var voteResult = new VoteResult()
            {
                QuestionId = result.Key,
                Percentage = ((float)result.Count() / total) * 100.0f
            };

            Console.WriteLine(voteResult.QuestionId);

            Console.WriteLine(voteResult.Percentage);
        }

    }
}
于 2012-08-21T13:33:48.933 に答える