【问题标题】:Rank records with cross-table column division使用跨表列划分对记录进行排名
【发布时间】:2018-12-22 11:13:53
【问题描述】:

我需要编写一个 SQL 查询,它根据来自不同表中的列的两个派生值的划分来带来排名记录。因此,表 1 有一个 A 列,表 2 有一个 B 列,两个表都有共同的school_id。表 A 中的数据如下所示:

school_id | student_id | subject_id | marks
123         ABC          7Y8U         94
234         UHT          4Y8U         87
123         ABC          8P0F         49
567         FCV          5Q1U         70

表B中的数据如下:

school_id | prize_amt
123         3000     
234         4700     
123         8210     
567         3200     

我需要做的计算是:

required_value = total marks per school per student / number of times that school is awarded

我需要在DESC 顺序中基于required_value 排列的n 记录。我现在可以写两个查询:

  • 仅针对给定学生按 DESC 顺序选择具有相应最高总分的不同学校
  • 选择学校按 DESC 顺序授予的次数

如何获得在上面定义的required_value 上排名的多条记录?期望的结果是:

school_id | required_value   
234         87     
123         71.50     
567         70  

因此,ID 为 123 的学校的分数为 94 + 49 = 143,并且获得了 2 次奖励,因此其 required_value 的值为 143/2 = 71.50。

【问题讨论】:

  • school_ids 891 和 901 是从哪里来的?它们不在样本数据中
  • @Mureinik 只是示例演示。让我更正一下。
  • @ShubhamA。你如何获得 required_value。你能把它放在你的查询中吗?什么是“每所学校每名学生的总分”?我真的不明白如何从 school_id 234 获得 29.67
  • 两张表中的数据之间存在1-1相关是巧合吗?
  • 您提供的示例数据似乎与预期结果不符。请至少向我们展示您如何计算 school_id 234 和 school_id 123 的 required_value。

标签: mysql sql select


【解决方案1】:
     select tableA.school_id,
    (sum(marks)/(count(tableA .school_id) *1.00)) as required_value   
    from tableA inner join tableB on tableA.school_id =tableB.school_id             
    group by school_id 
    order by (sum(marks)/(count(tableA.school_id) *1.00)) desc

【讨论】:

  • @shubham 有帮助吗?
  • 使用 tablename.column 名称作为你们两个表相同的列名称
  • 你能把它格式化一下,这样看起来就不会像一个 7 岁的孩子在做作业上吐槽了吗?这实际上是迄今为止最有效的解决方案。
  • 因此,在进一步挖掘时,您似乎幸运地查询此示例数据,在 TableA ((123, 'ABC', '7P0F', 32)) 中添加一个附加项目会破坏您的查询。使用新数据集查看 my queryyour query
  • 我真的不喜欢抱怨@FrankerZ
【解决方案2】:

我会使用两个聚合查询,一个是对每所学校的分数求和,一个是对奖励进行计数,将它们加入学校 ID 并划分结果:

SELECT   a.school_id, sum_marks / num_awards
FROM     (SELECT   school_id, SUM(marks) AS sum_marks
          FROM     a
          GROUP BY school_id) a
JOIN     (SELECT   school_id, COUNT(*) AS num_awards
          FROM     b
          GROUP BY school_id) b ON a.school_id = b.school_id
ORDER BY 2 DESC

【讨论】:

    【解决方案3】:

    我可以用这个查询做到这一点:

    SELECT a.school_id, total_marks/COUNT(b.school_id) as required_value FROM (
      SELECT school_id, SUM(marks) AS total_marks
      FROM TableA
      GROUP BY school_id
    ) a
    LEFT JOIN TableB b on a.school_id = b.school_id
    GROUP BY a.school_id
    ORDER BY required_value DESC
    

    1st,进行原始查询以获得总分,按学校分组:

    SELECT school_id, SUM(marks) AS total_marks
    FROM TableA
    GROUP BY school_id
    

    从那里开始,这是一个简单的左连接(获取学校获得奖励的所有次数COUNT(b.school_id)),然后做一些数学运算!

    请参阅 sql fiddle here

    现在,进入性能。这似乎比上面@Mureinik 的查询性能略高,因为您使用的是 1 个派生表而不是 2 个:

    我的查询:

    穆林克的疑问:

    对于小型数据集,这应该没什么关系,但是当数据集增长时,这个查询会逐渐变慢。

    【讨论】:

    • 这也是一个很好的比较。谢谢,让我尝试查询并返回输出。
    猜你喜欢
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 2017-11-04
    • 2014-08-13
    相关资源
    最近更新 更多