【问题标题】:In mysql how do I query at, above, and below values for each score across multiple tests? Bonus points if there is calculated percentile rankings在 mysql 中,我如何查询多个测试中每个分数的值,高于和低于值?如果有计算的百分位排名,则加分
【发布时间】:2013-03-05 11:05:49
【问题描述】:

tbl 分数:(csv;我不知道如何在此处格式化表格架构)

test_id, student_id, score   
1, 1, 75  
1, 2, 84  
1, 3, 60  
2, 1, 82  
1, 4, 90  
1, 5, 75  
2, 2, 70  
2, 3, 90  
2, 5, 76   

我需要做的是,对于每个分数的每个测试,计算该分数的学生人数,然后计算每个测试的分数是多少百分比。

我已使用查询成功地按每个分数计算学生人数:

SELECT test_id, score, COUNT(student_id) as num_students FROM Scores GROUP BY test_id, score

此时我正在尝试获取每个测试的每个分数的#at、#below 和#above,以便我可以尝试计算每个分数的百分位数。

这会是某种数据透视表吗?

【问题讨论】:

    标签: mysql sql subquery pivot-table


    【解决方案1】:

    在 MySQL 中,您需要使用相关子查询来执行此操作。以下是学生人数的示例:

     SELECT test_id, score, COUNT(student_id) as num_students,
            (select count(*) from scores s2 where s2.test_id = s.test_id and s2.score < s.score
            ) as below
     FROM Scores s
     GROUP BY test_id, score
    

    【讨论】:

    • 实际上,这大约有 100 万条记录,用于约 300 次测试,约 4k 独特分数。这是用于报告的,每年仅访问几次。这似乎是一个非常昂贵的查询,几乎类似于 php 中的暴力破解(尽管在 sql 中 def 更简单)。为了学习,有没有更快的方法来解决这个问题?谢谢
    • 您能否详细说明为什么需要关联子查询?
    • @JakubKania 。 . .因为 MySQL 不提供任何其他机制来进行累积和。您可以使用非等值连接来表达相同的想法,但这本质上是等价的。
    • @Gordon Linoff 顺便说一句,这让我进入下一步,谢谢。在我的完整数据集上,我可能会在运行此程序时去吃午饭,但我将能够在一个查询中输出必要的数据!
    【解决方案2】:

    它不一定是相关的,但由于交叉连接和不同,它可能会表现得更差我不确定它会表现得更好还是更差

    SELECT s.test_id, 
           s.score, 
           Count(DISTINCT s.student_id) AS num_students, 
           Count(DISTINCT z.student_id) AS below 
    FROM   scores s 
           LEFT JOIN scores z 
                  ON s.test_id = z.test_id 
                     AND s.score > z.score 
    GROUP  BY s.test_id, 
              s.score 
    ORDER  BY s.test_id, 
              s.score; 
    

    是的 http://sqlfiddle.com/#!2/fd824/13

    【讨论】:

      猜你喜欢
      • 2023-02-09
      • 2020-03-19
      • 1970-01-01
      • 2010-11-06
      • 2012-02-27
      • 2019-03-27
      • 2013-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多