用于复杂查询的MySQL子查询未知列

时间:2015-02-16 17:51:46

标签: mysql

我有以下sqlfiddle http://sqlfiddle.com/#!2/324628/1

我需要创建一个查询,以返回其班级中每个学生的id和位置(排名);根据{{​​1}}表中存储的学术平均值,该职位按降序排序。

(例如,第1级的第一级,第1级的第二级,依此类推......第2级的第一级,第2级的第二级......)

以下是查询:

academic_averages

但是,由于它包含子查询,我无法将WHERE从最内层查询更改为SELECT students.id, (SELECT x.position FROM ( SELECT t.student_id, t.value, @rownum := @rownum + 1 AS position FROM ( SELECT aa.student_id, aa.value FROM academic_averages AS aa INNER JOIN students AS s ON s.id = aa.student_id INNER JOIN classes_students AS cs ON cs.student_id = s.id INNER JOIN classes_academic_years AS cas ON cas.id = cs.class_academic_year_id INNER JOIN classes_academic_years as cas2 on cas2.class_id = cas.class_id INNER JOIN classes_students as cs2 on cs2.class_academic_year_id = cas2.id INNER JOIN students as s2 on s2.id = cs2.student_id WHERE s2.id = 243 AND cas.academic_year_id = 4 AND aa.academic_year_id = 4 GROUP BY aa.student_id ORDER BY abs(aa.value) DESC ) t JOIN (SELECT @rownum := 0) r ) AS x WHERE x.student_id = students.id ) AS ranking_by_class FROM students ,因为它会抛出错误(未知列)。

我尝试过使用INNER JOIN而不是子查询,但到目前为止还没有运气。

有没有人有解决方案?

由于

LE:性能明智,必须优化查询

LE:这是表格的结构:

academic_averages

s2.id = students.id

classes_academic_years

id
student_id
value
academic_year_id

classes_students

id
class_id
name
grade
academic_year_id

id
class_academic_year_id
student_id

id
school_id

所需的输出应为id 。 sql小提琴似乎存在一些问题,同时这里是架构:http://snippi.com/s/db8za8k

1 个答案:

答案 0 :(得分:1)

SELECT x.id
  , x.position
  , x.academic_average
FROM (SELECT
  s.id
  , @rownum := @rownum + 1 position
  , av.value academic_average
FROM students s
JOIN classes_students cs ON s.id = cs.student_id 
JOIN classes_academic_years cay ON cay.id = cs.class_academic_year_id
JOIN academic_averages av ON av.student_id = s.id
WHERE cay.academic_year_id = 4 -- change these two parameters in    
  AND  av.academic_year_id = 4 -- the subquery for different years
ORDER BY av.value DESC) x,
(SELECT @rownum := 0) y
ORDER BY academic_average DESC

我认为以上查询应该适合您。

我假设学术排名position是按学术平均数的降序确定的。

我无法访问您的数据集,因此我添加了三行,两行用于选择学生的学术平均值,另一行根据学术平均值按降序排列结果。这应该可以帮助您验证它是否按预期工作。如果您运行查询,并且它可以工作,它应该显示position从1开始并递增1的记录。

在制作中,我会省略这些片段以获得您指定的结果集:
1. , x.academic_average
2. , av.value academic_average
3. ORDER BY academic_average DESC

编辑OP 的评论中的详细说明(课程要求的学生排名)

此查询应该按班级为您提供学生的位置。如果要删除某些字段,可以将SELECT包装在另一个SELECT中,或者在将数据集提取到另一种语言后忽略列。

SELECT 
    x.student_id
  , x.cay_class_id
  , x.academic_average
  , if(@classid = x.cay_class_id, @rownum := @rownum + 1, @rownum := 1) position
  , @classid := x.cay_class_id
FROM (SELECT
    s.id student_id
  , cay.class_id cay_class_id
  , av.value academic_average

FROM students s
JOIN classes_students cs ON s.id = cs.student_id 
JOIN classes_academic_years cay ON cay.id = cs.class_academic_year_id
JOIN academic_averages av ON av.student_id = s.id
WHERE cay.academic_year_id = 4 -- change these two parameters in    
  AND  av.academic_year_id = 4 -- the subquery for different years
ORDER BY cay.class_id, av.value DESC) x,
(SELECT @classid := 0, @rownum := 0) y