在 mysql 和 oracle 中按查询分组
Posted
技术标签:
【中文标题】在 mysql 和 oracle 中按查询分组【英文标题】:Group by query in mysql and oracle 【发布时间】:2014-01-27 08:15:45 【问题描述】:我创建了一个表并尝试学习如何使用 group by query,但它给出了奇怪的输出。
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');
现在我正在尝试根据分支对学生进行排序。为此,我尝试了以下查询
在甲骨文中
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 等网站进行引用。但是看不懂。
【问题讨论】:
GROUP BY 语句与聚合函数结合使用,将结果集按一列或多列分组 MySQL 对group by
运算符的实现非常草率(更不用说损坏了)。请参阅此:rpbouman.blogspot.de/2007/05/debunking-group-by-myths.html 和此:mysqlperformanceblog.com/2006/09/06/… 了解更多详情
对于oracle,你需要使用聚合函数来使用group by子句。
谢谢大家。谢谢@a_horse_with_no_name。链接非常好,对我帮助很大。
【参考方案1】:
Group by 仅在与 sum() 等其他聚合函数一起使用时才有意义。 这些聚合函数组合了列的几行的值。 例如 sum() 计算指定列的所有值的总和。在您的示例中,这些列可以是 totfee 或 feepaid。但这会计算所有行的总和,如果要单独计算每个分支的总和,可以在分支列上使用 group by 子句。现在,您的数据库计算具有相同 branch-value 的行的聚合函数,结果包含与表中 branch 的不同值相同的行数.
【讨论】:
【参考方案2】:您不能选择未聚合且不在GROUP BY
子句中的字段。
与 MySQL 相比,Oracle 对此规则更为严格。 MySQL 只取第一个值,但 Oracle 抛出错误。
此外,GROUP BY
用于对记录进行分组(聚合)。要对结果进行排序,您应该使用ORDER BY
。
【讨论】:
【参考方案3】:'group by branch' 将返回'branch' 字段的所有不同值。 如果要根据“分支”字段对学生进行排序,则应使用“按分支 ASC 排序”(或 DESC)。
【讨论】:
【参考方案4】:正如您所说,您想根据分支对学生进行排序,而不是使用“group by”,您可以使用“order by”。
select * from student order by branch;
【讨论】:
【参考方案5】:在 oracle 中,您可以使用此查询来获得最终结果:
with Tab AS (SELECT min(BID) AS ID FROM STUDENT GROUP BY BRANCH)
SELECT * FROM STUDENT WHERE BID IN (SELECT ID FROM Tab);
【讨论】:
【参考方案6】:在 Oracle 中,您必须在 select 语句中为 group by 表达式中使用的每一列命名,如果您在 select 语句中使用 *,则必须按表达式为 group 中的所有列命名: 从学生中选择 * 按 s.bid、s.sname、s.totfee、s.feepaid、s.feebal、s.branch、s.city 分组 这不是真正的分组,上面的查询等于从学生中选择*,并且没有真正进行分组。 你可以在 Oracle 中进行这样的查询:
每个分行的最高totfee:
select s.branch,max(s.totfee) from student s group by s.branch
在这个查询中,oracle 根据它们的分支对所有数据进行分组。 基于分支的分组意味着您的输出中每个分支(如“amr”)应该只有 1 条记录,通常分支“amr”有 3 条记录,因此您应该做一些工作来删除额外的行,并且您应该告诉 oracle 哪个应该删除哪些行,应该保留哪些行,这是 max(s.totfee) 存在的原因,具有 max 功能,您说 oracle 只保留具有最大 totfee 的行并删除其他行,现在您可以拥有 1每个分支的输出记录。
提示:如果你想暗示一个条件,你应该在上面的查询中使用“have”而不是 where。
拥有超过 2 名学生的分支机构数量:
select s.branch,count(*) from student s group by s.branch having count(*)>2
【讨论】:
以上是关于在 mysql 和 oracle 中按查询分组的主要内容,如果未能解决你的问题,请参考以下文章