【问题标题】:select top 10 students from database [duplicate]从数据库中选择前 10 名学生 [重复]
【发布时间】:2011-07-29 05:19:40
【问题描述】:

可能重复:
sql to select top 10 records

假设您有一张表,其中包含 StuId、StuName、Subject、Grade。您需要提供子查询以返回按平均成绩排序的荣誉学生(前 10%)列表。

例如,如果我有 10 个学生,他们的平均成绩是 100,90,80,...10。 要求输出第一个平均为100的学生姓名,只输出一个学生成绩。所以我不能使用limit 10

我正在使用 mysql 5.1。

这是我的查询:

SELECT Stuname, TOP 10 Avg(Grade) as GPA 
  FROM Table 
GROUP BY Stuid 
ORDER BY GPA

由于TOP 10,查询不正确。查看MYSQL 5.1参考,不支持top 10。

根据cmets的说法,我觉得用一个查询是解决不了的,所以想出一个方法:

F(conn){
Statement stmt;
int top10percnet = 0;
try{
stmt = conn.createStatement;
String query = "select CEIL(count(stuname)*10/100) as 10percent from grades";
ResultSet rs = stmt.execute(query);
while(rs.next()){
  top10percent = rs.getString("10percent");
}
query = "select stuname, avg(grade) as average from grades group by stuname order
by average desc limit " + Integer.toString(top10percnet);
rs=stmt.execute(query);
while(rs.next()){
   ...// output result
}
}
catch(SQLException e){
}



}  

【问题讨论】:

  • 我很好奇,你能链接到引用 TOP 子句的 MySQL 文档吗?
  • 我之前的问题要求不清楚,所以编辑一下。我期待的不是前 10 名学生,而是前 10% 的学生。可能是一个人,零个人。
  • 我已经相应地更新了我的答案

标签: mysql sql


【解决方案1】:
count = select CEIL(count(Stuname)*10/100) from table_name;
select Stuname from table_name ORDER BY GPA DESC limit count;

第一个查询将返回 10% 的学生。CEIL 用于将其转换为整数。 第二个查询是检索数据。 从第一个查询计算的计数设置为第二个查询的限制。

【讨论】:

  • 一些建议,详细一点,以便其他人更好地理解您的解决方案。
【解决方案2】:

使用LIMITDESC 顺序(即从高到低):

select Stuname, Avg(Grade) as GPA
from Table
group by Stuid
order by 1 DESC -- Add DESC
LIMIT 10 -- Add LIMIT

【讨论】:

  • 不应该是order by GPA DESC,而不是2吗?
  • @Shurane MySQL 支持ORDER BY 子句中的列索引
  • 两者都可以。由于 SQL92,group byorder by 可以采用列号而不是表达式
  • @Shurane:这个答案使用序数值,基于 SELECT 子句中的位置。这是有效的,但不是推荐的做法,因为如果有人在第一列或两个现有列之间添加一列 - ORDER BY 将不一样,它将按列表中第二列的任何列排序。
  • @Bohemian 不记得它是不是那些神奇的 MySQL 事物之一,但如果列不是选择的一部分,GROUP BY 是否有效?
【解决方案3】:

更新

听起来您想加入 HAVING 子句,以将结果限制为平均成绩高于 90 分的人。

试试

SELECT Stuid, Stuname, AVG(Grade) AS GPA FROM Table
GROUP BY Stuid, Stuname
HAVING AVG(GRADE) > 90
ORDER BY GPA DESC -- If you want highest-to-lowest. Thanks Bohemian

【讨论】:

  • 对不起,错了。这将给出 LOWEST 10
  • @Bohemian 只需使用 OP 中的代码
  • 代码也有同样的问题。 -1 已移除 :)(你已修复)
  • HAVING,也不是 AVG,解决了百分比要求。我已要求 OP 恢复更改、标记并回答并发布有关百分比的新问题。
  • @OMGPonies 是的,我不完全确定 OP 的目标是什么。我现在看到他们想要找到的所有记录中的前 10%
【解决方案4】:

TOP 是 SQL Server 2000+ 特定的; MySQL 使用LIMIT 语法——ANSI 也不是,直到最近FETCH FIRST 10 ROWS ONLY 才使用 ANSI(DB2 是我所知道的唯一支持它的 DB)。

因为您将问题标记为“mysql”:

  SELECT t.stuname,
         AVG(t.grade) AS grade_avg
    FROM TABLE t
GROUP BY t.stuname
ORDER BY grade_avg DESC
   LIMIT 10

对于 SQL Server 2000+,查询将是:

  SELECT TOP 10
         t.stuname,
         AVG(t.grade) AS grade_avg
    FROM TABLE t
GROUP BY t.stuname
ORDER BY grade_avg DESC

TOP 始终位于SELECT 子句中的列之前。从 SQL Server 2005+ 开始,您可以在顶部值周围使用方括号以允许您使用变量:

DECLARE @int_var INT
SET @int_var = 10

  SELECT TOP (@int_var)
         t.stuname,
         AVG(t.grade) AS grade_avg
    FROM TABLE t
GROUP BY t.stuname
ORDER BY grade_avg DESC

这允许您动态设置TOP,而无需动态SQL。

【讨论】:

  • @SecureFish:这是第一个查询的用途——每个查询适用的数据库都在每个查询之前说明...
  • 第一次发的时候问题不清楚(现在已经修改)。它不是前 10 名记录,而是前 10% 的记录。例如,如果您有 10 条记录,则只会输出第一条记录。
  • @SecureFish:所以在得到一些答案之后,您意识到您的要求已经过时了吗?我们不会收到有关问题更新的通知;出于尊重,我建议您恢复您的更新,选择一个答案,然后发布另一个问题来询问有关获取百分比的问题。
【解决方案5】:

您是否尝试过使用 LIMIT 代替?

例如

select Stuname, Avg(Grade) as GPA from Table group by Stuid order by GPA limit 10

【讨论】:

  • 行不通。这将给出 LOWEST 10
猜你喜欢
  • 2014-08-26
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2014-02-28
  • 2018-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多