完全理解GROUP BY时遇到问题

7 sql oracle

我正在为一个考试做一些练习题,我已经出现了,我有一个完全理解小组的问题.我看到GROUP BY如下:将结果集分组为一列或多列.

我有以下数据库架构

在此输入图像描述

在此输入图像描述

我的查询

SELECT orders.customer_numb, sum(order_lines.cost_line), customers.customer_first_name, customers.customer_last_name
FROM orders
INNER JOIN customers ON customers.customer_numb = orders.customer_numb
INNER JOIN order_lines ON order_lines.order_numb = orders.order_numb
GROUP BY orders.customer_numb, order_lines.cost_line, customers.customer_first_name,     customers.customer_last_name
ORDER BY order_lines.cost_line DESC
Run Code Online (Sandbox Code Playgroud)

我正在努力理解
为什么我不能简单地使用GROUP BY orders.cost_linecost_line来对数据进行分组?

我想要实现的目标
我希望获得花费最多的客户的名字.我只是不完全明白如何实现这一目标.我理解联接是如何工作的,我似乎无法理解为什么我不能简单地使用GROUP BY customer_numb和cost_line(用sum()来计算花费的金额).我似乎总是得到"不是GROUP BY表达",如果有人可以解释我做错了什么(不只是给我答案),这将是伟大的 - 我真的很感激,当然任何资源,你必须正确使用GROUP.

对于这篇长文章我很抱歉,如果我错过任何我道歉的话.任何帮助将不胜感激.

Sha*_*nce 6

我似乎无法理解为什么我不能简单地使用GROUP BY customer_numb和cost_line(用sum()来计算花费的金额).

当你说group by customer_numb你知道customer_numb唯一标识客户表中的一行(假设customer_numb是主要或备用键),使任何给定customers.customer_numb将有且只有一个值customers.customer_first_namecustomers.customer_last_name.但是在解析时Oracle不知道,或者至少表现得像它不知道那样.它有点恐慌地说,"如果一个人customer_numb有多个值,我该怎么办customer_first_name?"

大致规则是,select子句中的表达式可以使用子句中的表达式group by和/或使用聚合函数.(以及不依赖于基表的常量和系统变量等)和"使用"我的意思是表达式或表达式的一部分.因此,一旦您对名字和姓氏进行分组,customer_first_name || customer_last_name也将是一个有效的表达式.

如果您有一个表,类似于customers并通过主键分组,或者使用唯一键而不是空约束的列,则可以安全地将它们包含在group by子句中.在这个特定的例子中,group by customer.customer_numb, customer.customer_first_name, customer.customer_last_name.

另请注意,order by第一个查询中的失败,因为order_lines.cost_line该组没有单个值.您可以sum(order_lines.cost_line)select子句中订购或使用列别名,并对其进行排序alias

SELECT orders.customer_numb, 
    sum(order_lines.cost_line), 
    customers.customer_first_name, 
    customers.customer_last_name
FROM orders
INNER JOIN customers ON customers.customer_numb = orders.customer_numb
INNER JOIN order_lines ON order_lines.order_numb = orders.order_numb
GROUP BY orders.customer_numb, 
    customers.customer_first_name, 
    customers.customer_last_name
ORDER BY sum(order_lines.cost_line)
Run Code Online (Sandbox Code Playgroud)

要么

SELECT orders.customer_numb, 
    sum(order_lines.cost_line) as sum_cost_line, 
. . .
ORDER BY sum_cost_line
Run Code Online (Sandbox Code Playgroud)

注意:我听说有些RDBMS会暗示分组的其他表达式而不明确说明.Oracle不是那些RDBMS之一.

至于两者的分组customer_numb,cost_line考虑一个有两个客户的数据库,1和2,每个订单有两个订单:

Customer Number | Cost Line
              1 |     20.00
              1 |     20.00
              2 |     35.00
              2 |     30.00

 select customer_number, cost_line, sum(cost_line)
 FROM ...
 group by customer_number, cost_line
 order by sum(cost_line) desc

Customer Number | Cost Line | sum(cost_line)
              1 |     20.00 |          40.00
              2 |     35.00 |          35.00
              2 |     30.00 |          30.00
Run Code Online (Sandbox Code Playgroud)

最高的第一行sum(cost_line)不是花费最多的客户.