【问题标题】:self join in sql for generating Rank在sql中自我加入以生成排名
【发布时间】:2012-12-05 19:45:01
【问题描述】:

我想根据他获得的分数计算每个学生的排名。但如果标记在 -ve 值中,则查询不会显示适当的答案。

SELECT a1.ResultByTestId, a1.ObtainedMarks, COUNT(a2.ObtainedMarks) Rank
 FROM ResultByTest a1, ResultByTest a2
WHERE a1.ObtainedMarks < a2.ObtainedMarks 
      or 
      (a1.ObtainedMarks=a2.ObtainedMarks and a1.StudentId = a2.StudentId)
GROUP BY  a1.ObtainedMarks, a1.ResultByTestId
ORDER BY a1.ObtainedMarks DESC, Rank DESC

答案表是:-

resutlByTestId  ObtainedMarks  Rank

11                36              1
10                22              2
3                  9              3
9                  7              4
6                  5              5
8                  3              6
7                  2              7
4                  0              8
5                  0              8
1                  0              8
2                  0              8
13                -5              12

有人帮帮我吗?

【问题讨论】:

    标签: sql sql-server-2008 join


    【解决方案1】:

    您可以使用Dense_Rank 函数来做到这一点

    Select
      StudentID,
      ObtainedMarks,
      Dense_Rank() Over (Order By ObtainedMarks Desc) as Rank
    From 
      ResultByTest
    

    http://sqlfiddle.com/#!3/a9e5c/1

    您通常使用排名的原因是,当您询问获得 -5 的人您从哪里来时,他们会说“第 9 位”。那你问,有多少人打你“12”。然后你看起来很困惑。

    【讨论】:

      【解决方案2】:

      您应该在 MSSQL 2008 中使用 DENSE_RANK() function

      SELECT ResultByTestId, ObtainedMarks, 
             DENSE_RANK() OVER (order by ObtainedMarks desc) as Rank
       FROM ResultByTest
      ORDER by ObtainedMarks DESC;
      

      这也是您对COUNT(DISTINCT &lt;&gt;)的查询:

      SELECT a1.ResultByTestId, a1.ObtainedMarks, 
       COUNT(DISTINCT a2.ObtainedMarks) Rank
       FROM ResultByTest a1, ResultByTest a2
      WHERE a1.ObtainedMarks < a2.ObtainedMarks 
            or 
            (a1.ObtainedMarks=a2.ObtainedMarks and a1.StudentId = a2.StudentId)
      GROUP BY  a1.ObtainedMarks, a1.ResultByTestId
      ORDER BY a1.ObtainedMarks DESC, Rank DESC
      

      【讨论】:

      • 然后只需更改您的查询COUNT(DISTINCT a2.ObtainedMarks)
      • 非常感谢。但是你能告诉我,如果我想使用你建议的 Rank() 函数来计算排名。
      • 然后用DENSE_RANK()代替RANK
      【解决方案3】:

      输出正确没有问题,因为 -ve 分数,四个学生得了 0,排名第 8 所以 8-8 8-9 8-10 8-11

      这就是它的计数方式,所以下一个排名显然是 12

      【讨论】:

      • 是的,我知道它正在计算 8 排名 4 次所以下一个排名是 12,这对我来说是个问题,我希望排名 9 在 8 之后而不是 12。
      【解决方案4】:
      --setup test data
      
      DECLARE @ResultByTest TABLE (ResultByTestId int, ObtainedMarks int)
      
      INSERT INTO @ResultByTest VALUES
      (11,                36),
      (10,                22),
      (3,                  9),
      (9,                  7),
      (6,                  5),
      (8,                  3),
      (7,                  2),
      (4,                  0),
      (5,                  0),
      (1,                  0),
      (2,                  0),
      (13,                -5)
      
      -- this will give you the results you have
      
      select *, RANK() OVER (ORDER BY ObtainedMarks DESC) AS [Rank]
      from @ResultByTest
      
      -- this will give you the results I think you want
      
      select *, DENSE_RANK() OVER (ORDER BY ObtainedMarks DESC) AS [Rank]
      from @ResultByTest
      

      【讨论】:

        【解决方案5】:

        使用 DENSE_RANK 消除差距。

        DECLARE @ObtainedMarks TABLE (
        ResultByTestId INT,
        ObtainedMarks INT,
        StudentId INT
        
        )
        
        INSERT INTO @ObtainedMarks VALUES
        (1,0,1),
        (2,0,1),
        (3,9,1),
        (4,0,1),
        (5,0,1),
        (6,5,1),
        (7,2,1),
        (8,3,1),
        (9,7,1),
        (10,22,1),
        (11,36,1),
        (13,-5,1)
        
        SELECT 
            ResultByTestId,
            ObtainedMarks,
            DENSE_RANK() OVER (order by ObtainedMarks desc) [Rank]
        FROM @ObtainedMarks
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多