检索表中最大出现的值

时间:2015-07-10 22:09:16

标签: mysql sql

我的问题非常复杂。让我先解释一下我现在在做什么:

我有一个表名feedback,其中我根据课程ID存储成绩。该表如下所示:

+-------+-------+-------+-------+-----------+--------------
| id    | cid   | grade |g_point| workload  | easiness
+-------+-------+-------+-------+-----------+--------------
| 1     |  10   |  A+   |   1   |      5    |   4
| 2     |  10   |  A+   |   1   |      2    |   4
| 3     |  10   |  B    |   3   |      3    |   3
| 4     |  11   |  B+   |   2   |      2    |   3
| 5     |  11   |  A+   |   1   |      5    |   4
| 6     |  12   |  B    |   3   |      3    |   3
| 7     |  11   |  B+   |   2   |      7    |   8
| 8     |  11   |  A+   |   1   |      1    |   2

g_point只有等级的特定值,因此我可以使用这些值来显示按等级排序的用户课程。

好的,现在首先我的任务是打印出每个课程的gradegrade可以通过针对每个课程的最大出现次数来计算。例如,从此表中我们可以看到cid = 10的结果将是A+,因为它在那里出现了两次。这很简单。我已经实现了这个查询,最后我将在这里写。

主要问题是当我们谈论有两个不同等级的课程cid = 11时。现在,在这种情况下,客户要求我考虑这些课程的平均工作量和容易程度,以及应该显示更高平均值的任何课程。平均值将如下计算:

  all workload values of the grade against course
+ all easiness values of the grade against course
/ 2 

在此示例中,cid = 11有四个条目,与课程的成绩相同

B+平均成绩

avgworkload(2 + 7)/2=x 
avgeasiness(3 + 8)/2 = y

回答x + y / 2 = 10

A+平均成绩

 avgworkload(5 + 1)/2=x 
avgeasiness(4 + 2)/2 = y

  answer x+y/2 = 3

所以成绩应为B+

这是我为了获得最大发生等级而运行的查询

SELECT
    f3.coursecodeID cid,
    f3.grade_point p,
    f3.grade g
FROM (
    SELECT
        coursecodeID,
        MAX(mode_qty) mode_qty
    FROM (
        SELECT
            coursecodeID,
            COUNT(grade_point) mode_qty
        FROM feedback
        GROUP BY
            coursecodeID, grade_point
    ) f1
    GROUP BY coursecodeID
) f2
INNER JOIN (
    SELECT
        coursecodeID,
        grade_point,
        grade,
        COUNT(grade_point) mode_qty
    FROM feedback
    GROUP BY
        coursecodeID, grade_point
) f3
ON
    f2.coursecodeID = f3.coursecodeID AND
    f2.mode_qty = f3.mode_qty
GROUP BY f3.coursecodeID
ORDER BY f3.grade_point

2 个答案:

答案 0 :(得分:1)

这是SQL Fiddle。 我添加了一个表Sub anotheroverflowquestion() 'Turn on References to Microsoft Internet Controls Dim IE As New InternetExplorer MsgBox TypeName(IE) End Sub ,其中包含所有课程ID的列表,以便更容易看到查询的主要概念。很可能你在真正的数据库中拥有它。如果没有,您可以通过Courses分组从feedback动态生成。

对于每个cid,我们需要找到cid。按gradefeedback进行分组,以获取cid, grade所有成绩的列表。我们只需为cid选择一个成绩,因此我们使用cid。要确定选择哪个等级,我们会订购它们。首先,通过出现 - 简单LIMIT 1。第二,按平均分。最后,如果有多个成绩相同且具有相同的平均成绩,则选择具有最小COUNT的成绩。您可以通过调整g_point子句来调整规则。

ORDER BY

结果集

SELECT
  courses.cid
  ,(
    SELECT feedback.grade
    FROM feedback
    WHERE feedback.cid = courses.cid
    GROUP BY
      cid
      ,grade    
    ORDER BY 
      COUNT(*) DESC
      ,(AVG(workload) + AVG(easiness))/2 DESC
      ,g_point
    LIMIT 1
  ) AS CourseGrade
FROM courses
ORDER BY courses.cid

<强>更新

MySQL没有横向连接,因此获得第二列cid CourseGrade 10 A+ 11 B+ 12 B 的一种可能方法是重复相关的子查询。 SQL Fiddle

g_point

结果集

SELECT
  courses.cid
  ,(
    SELECT feedback.grade
    FROM feedback
    WHERE feedback.cid = courses.cid
    GROUP BY
      cid
      ,grade    
    ORDER BY 
      COUNT(*) DESC
      ,(AVG(workload) + AVG(easiness))/2 DESC
      ,g_point
    LIMIT 1
  ) AS CourseGrade
  ,(
    SELECT feedback.g_point
    FROM feedback
    WHERE feedback.cid = courses.cid
    GROUP BY
      cid
      ,grade    
    ORDER BY 
      COUNT(*) DESC
      ,(AVG(workload) + AVG(easiness))/2 DESC
      ,g_point
    LIMIT 1
  ) AS CourseGPoint
FROM courses
ORDER BY CourseGPoint

更新2 将平均分数添加到cid CourseGrade CourseGPoint 10 A+ 1 11 B+ 2 12 B 3 SQL Fiddle

ORDER BY

<强>结果

SELECT
  courses.cid
  ,(
    SELECT feedback.grade
    FROM feedback
    WHERE feedback.cid = courses.cid
    GROUP BY
      cid
      ,grade    
    ORDER BY 
      COUNT(*) DESC
      ,(AVG(workload) + AVG(easiness))/2 DESC
      ,g_point
    LIMIT 1
  ) AS CourseGrade
  ,(
    SELECT feedback.g_point
    FROM feedback
    WHERE feedback.cid = courses.cid
    GROUP BY
      cid
      ,grade    
    ORDER BY 
      COUNT(*) DESC
      ,(AVG(workload) + AVG(easiness))/2 DESC
      ,g_point
    LIMIT 1
  ) AS CourseGPoint
  ,(
    SELECT (AVG(workload) + AVG(easiness))/2
    FROM feedback
    WHERE feedback.cid = courses.cid
    GROUP BY
      cid
      ,grade    
    ORDER BY 
      COUNT(*) DESC
      ,(AVG(workload) + AVG(easiness))/2 DESC
      ,g_point
    LIMIT 1
  ) AS AvgScore
FROM courses
ORDER BY CourseGPoint, AvgScore DESC

答案 1 :(得分:0)

如果我理解得很清楚你需要一个内部选择来找到平均值,第二个外部选择来找到平均值的最大值

select cid, grade, max(average)/2 from (
    select cid, grade, avg(workload + easiness) as average
    from feedback
    group by cid, grade
) x group by cid, grade

此解决方案已在此link

上对您的数据进行测试

如果您将上一个查询更改为

select cid,  max(average)/2 from (
    select cid, grade, avg(workload + easiness) as average
    from feedback
    group by cid, grade
) x group by cid

您将找到每个cid的最大平均值。

如评论中所述,如果您有更多的成绩达到最高平均水平,您必须选择使用策略。例如,如果你有

+-------+-------+-------+-------+-----------+--------------
| id    | cid   | grade |g_point| workload  | easiness
+-------+-------+-------+-------+-----------+--------------
| 1     |  10   |  A+   |   1   |      5    |   4
| 2     |  10   |  A+   |   1   |      2    |   4
| 3     |  10   |  B    |   3   |      3    |   3
| 4     |  11   |  B+   |   2   |      2    |   3
| 5     |  11   |  A+   |   1   |      5    |   4
| 9     |  11   |  C    |   1   |      3    |   6

您将获得A +和C等级,以满足最高平均值4.5