我正在为一个考试做一些练习题,我已经出现了,我有一个完全理解小组的问题。我看到 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
我正在努力理解
为什么我不能只使用GROUP BY orders.cost_line
并按cost_line对数据进行分组?
我想要实现的目标
我想获得花费最多钱的客户的名字。我只是不完全明白如何实现这一目标。我理解联接是如何工作的,我似乎无法理解为什么我不能简单地使用GROUP BY customer_numb和cost_line(用sum()来计算花费的金额)。我似乎总是得到“不是GROUP BY表达”,如果有人可以解释我做错了什么(不只是给我答案),这将是伟大的 - 我真的很感激,当然任何资源,你必须正确使用GROUP。
对于这篇漫长的文章感到抱歉,如果我错过了任何我道歉的话。任何帮助将不胜感激。
答案 0 :(得分:6)
我似乎无法理解为什么我不能简单地使用GROUP BY customer_numb和cost_line(sum()用于计算金额 略去)。
当您说group by customer_numb
时,您知道customer_numb唯一标识了customer表中的一行(假设customer_numb是主键或备用键),因此任何给定的customers.customer_numb
都只有一行customers.customer_first_name
customers.customer_last_name
和customer_numb
的值。但是在解析时Oracle不知道,或者至少表现得像它不知道那样。它有点恐慌地说:“如果一个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)
上订购
SELECT orders.customer_numb,
sum(order_lines.cost_line) as sum_cost_line,
. . .
ORDER BY sum_cost_line
或
customer_numb
注意:我听说有些RDBMS会暗示分组的其他表达式而不明确说明。 Oracle不是那些RDBMS之一。
至于cost_line
和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
的分组考虑一个有两个客户的数据库,1和2,每个客户有两个订单:
sum(cost_line)
最高{{1}}的第一行不是花费最多的客户。
答案 1 :(得分:3)
我理解联合是如何工作的,我似乎无法理解 为什么我不能简单地使用GROUP BY customer_numb和cost_line(使用sum()) 用于计算花费的金额。)
这应该为您提供每个客户的总和。
SELECT orders.customer_numb, sum(order_lines.cost_line)
FROM orders
INNER JOIN order_lines ON order_lines.order_numb = orders.order_numb
GROUP BY orders.customer_numb
请注意,SELECT子句中不聚合函数的参数的每一列也是GROUP BY子句中的一列。
现在您可以将其与其他表连接以获取更多详细信息。这是使用公用表表达式的一种方法。 (还有其他方式来表达你想要的东西。)
with customer_sums as (
-- We give the columns useful aliases here.
SELECT orders.customer_numb as customer_numb,
sum(order_lines.cost_line) as total_orders
FROM orders
INNER JOIN order_lines ON order_lines.order_numb = orders.order_numb
GROUP BY orders.customer_numb
)
select c.customer_numb, c.customer_first_name, c.customer_last_name, cs.total_orders
from customers c
inner join customer_sums cs
on cs.customer_numb = c.customer_numb
order by cs.total_orders desc
为什么我不能简单地使用GROUP BY orders.cost_line并将其分组 cost_line数据?
将GROUP BY应用于order_lines.cost_line将为order_lines.cost_line中的每个不同值提供一行。 (列orders.cost_line不存在。)这是数据的样子。
OL.ORDER_NUMB OL.COST_LINE O.CUSTOMER_NUMB C.CUSTOMER_FIRST_NAME C.CUSTOMER_LAST_NAME
--
1 1.45 2014 Julio Savell
1 2.33 2014 Julio Savell
1 1.45 2014 Julio Savell
2 1.45 2014 Julio Savell
2 1.45 2014 Julio Savell
3 13.00 2014 Julio Savell
您可以按order_lines.cost_line分组,但它不会为您提供任何有用的信息。此查询
select order_lines.cost_line, orders.customer_numb
from order_lines
inner join orders on orders.customer_numb = order_lines.customer_numb
group by order_lines.cost_line;
应该返回这样的内容。
OL.COST_LINE O.CUSTOMER_NUMB
--
1.45 2014
2.33 2014
13.00 2014
非常有用。
如果您对订单行项目的总和感兴趣,则需要确定要分组(汇总)的列。如果按订单编号进行分组(汇总),您将获得三行。如果按客户编号对(汇总)进行分组,您将获得一行。