I just can't understand why I can't just GROUP BY customer_numb and cost_line (with the amount () used to calculate the amount spent).
When you say group by customer_numb , you know that customer_numb uniquely identifies the row in the client table (assuming client_numb is either the primary or alternative key), so any given customers.customer_numb will have one and only one value for customers.customer_first_name and customers.customer_last_name . But in parsing time, Oracle does not know, or at least acts as if it does not. And he panics a bit: "What should I do if one customer_numb has more than one value for customer_first_name ?"
As a rule of thumb, expressions in a select clause can use expressions in a group by clause and / or use aggregate functions. (As well as constants and system variables that are independent of base tables, etc.). And by "use" I mean an expression or part of an expression. Therefore, when you group a first and last name, customer_first_name || customer_last_name customer_first_name || customer_last_name will also be correct.
When you have a table, such as customers , and are grouped using a primary key or a column with a unique key, and not with a null constraint, you can safely include them in the group by clause. In this particular case, group by customer.customer_numb, customer.customer_first_name, customer.customer_last_name.
Also note that order by in the first request will not work, since order_lines.cost_line does not have a single value for the group. You can order on sum(order_lines.cost_line) or use the column alias in the select clause and order on this 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)
or
SELECT orders.customer_numb, sum(order_lines.cost_line) as sum_cost_line, . . . ORDER BY sum_cost_line
Note. I heard that some RDBMS will imply additional expressions to group without explicitly specifying them. Oracle is not one of those RDBMS.
As for grouping both customer_numb and cost_line consider a database with two customers: 1 and 2 with two orders on the same 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
The first line with the highest sum(cost_line) not the client who spent the most.