我创建了一个表,并试图学习如何逐个查询,但它给出了奇怪的输出。
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。但无法理解。
答案 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