在 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() 计算指定列的所有值的总和。在您的示例中,这些列可以是 totfeefeepaid。但这会计算所有行的总和,如果要单独计算每个分支的总和,可以在分支列上使用 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 中按查询分组的主要内容,如果未能解决你的问题,请参考以下文章

在 MySQL 中按查询分组,忽略括号内的值

如何在oracle sql developer中按年和月分组获取当前财政年度的数据?

oracle和mysql中分组取特定的某一行的数据

在mysql和php中按日期范围分组

如何在 MySQL Select 语句中按多列分组

在 Django ORM 中按查询分组