通过mysql和oracle中的查询分组

时间:2014-01-27 08:15:46

标签: mysql oracle

我创建了一个表,并试图学习如何逐个查询,但它给出了奇怪的输出。

create table student(bid char(3), sname varchar(15), totfee float, feepaid float,
  feebal float, branch char(3), city char(4));


insert into student values(101,'student1',16000,8000,8000,'mat','bang');
insert into student values(102,'student2',17000,8000,9000,'mar','bang');
insert into student values(103,'student3',16000,9000,7000,'btm','bang');
insert into student values(104,'student4',12000,8000,4000,'amr','hyde');
insert into student values(105,'student5',14000,6000,8000,'mat','bang');
insert into student values(106,'student6',18000,8000,10000,'mar','bang');
insert into student values(107,'student7',16000,4000,12000,'btm','bang');
insert into student values(108,'student8',11000,2000,9000,'amr','bang');
insert into student values(109,'student9',13000,5000,8000,'btm','bang');
insert into student values(110,'student10',16000,3000,13000,'amr','hyde');

现在我正在尝试根据分支对学生进行排序。为此,我尝试了以下查询

在Oracle中

select * from student group by branch;

输出

  

错误 - 不是group by表达式

在Mysql中

输出是:

  +------+-----------+--------+---------+--------+--------+------+
  | bid  | sname     | totfee | feepaid | feebal | branch | city |
  +------+-----------+--------+---------+--------+--------+------+
  | 104  | student4  |  12000 |    8000 |   4000 | amr    | hyde |
  | 103  | student3  |  16000 |    9000 |   7000 | btm    | bang |
  | 113  | student13 |  36000 |   18000 |  18000 | mal    | bang |
  | 102  | student2  |  17000 |    8000 |   9000 | mar    | bang |
  | 101  | student1  |  16000 |    8000 |   8000 | mat    | bang |
  +------+-----------+--------+---------+--------+--------+------+

实际上我期待每一个人根据分支对所有学生进行分组。 那我该怎么做?什么是按查询分组的实际用途? 我甚至试过像w3school这样的网站引用,并且tpoint。但无法理解。

6 个答案:

答案 0 :(得分:3)

仅当与sum()或其他聚合函数一起使用时,分组才有意义。 这些聚合函数组合了列的多行的值。 例如,sum()计算指定列的所有值的总和。在您的示例中,这些列可以是 totfee 付费。但是这会计算所有行的总和,如果您希望单独计算每个分支的总和,则可以在分支列上使用group by子句。现在,您的数据库计算具有相同分支值的行的聚合函数,结果包含与表中分支的不同值相同的行数

答案 1 :(得分:2)

您无法选择未聚合且不在GROUP BY子句中的字段。 与MySQL相比,Oracle对此规则更严格。 MySQL只取第一个值,但Oracle会抛出错误。

此外GROUP BY用于分组记录(聚合)。要对结果进行排序,您应该使用ORDER BY

答案 2 :(得分:0)

'group by branch'将返回'branch'字段的所有不同值。 如果您想根据“分支”字段订购学生,您应该使用“按分支ASC排序”(或DESC)。

答案 3 :(得分:0)

正如您所说,您想要基于分支排序学生,而不是使用“分组依据”,您可以使用“order by”。

select * from student order by branch;

答案 4 :(得分:0)

在oracle中,您可以使用此查询来获得最终结果:

with Tab AS (SELECT min(BID) AS ID FROM STUDENT GROUP BY BRANCH)
SELECT * FROM STUDENT WHERE BID IN (SELECT ID FROM Tab);

答案 5 :(得分:0)

在Oracle中,您必须在select语句中按表达式命名组中使用的每个列,如果在select语句中使用*,则必须按表达式命名所有列: 从学生中选择* s.bid,s.sname,s.totfee,s.feepaid,s.feebal,s.branch,s.city 这不是真正的分组和上面的查询等于从学生中选择*,并且没有真正完成分组。 您可以在Oracle中进行此类查询:

每个分支的最大费用:

select s.branch,max(s.totfee) from student s group by s.branch  

在此查询中,oracle根据其分支对所有数据进行分组。 基于分支的分组意味着你的输出中每个分支只有1个记录,例如'amr',通常你有3个记录branch'amr',所以你应该做一些删除额外行的工作,你应该告诉oracle哪个行应删除,哪些应该保留,这是max(s.totfee)存在的原因,有max函数,你说oracle只保留最大totfee的行并删除其他行,现在你可以有1每个分支的输出记录。

提示:如果你想暗示一个条件,你应该使用'have'而不是上面的查询中的位置。

有超过2名学生的分支机构数量:

select s.branch,count(*) from student  s group by s.branch having count(*)>2