0

I'm learning SQL right now and I want to pull a certain data. However, the Alias is not recognized in the GROUP BY statement.

SELECT 
 E.FirstName + ' ' + E.LastName [Full Name],
 P.UnitPrice * P.UnitsInStock [Total Price]
FROM Employees E, Orders O, [Order Details] OD, Products P
WHERE 
 E.EmployeeID = O.EmployeeID
 and O.OrderID = OD.OrderID
 and OD.ProductID = P.ProductID
GROUP BY 
 [Full Name] --this is not recognized
HAVING 
 O.ShippedDate = null

I'm aware of the newer JOIN (I will change these habits). Also, the practice question was:

For each employee display the total price paid on all of his orders that hasn’t shipped yet.

We are talking on Northwind Microsoft Database. The Table Design is:

enter image description here

Even if the alias would work.. the query itself hasn't solve the question.

1

4 Answers 4

3

The alias won't work in the query's GROUP BY because aliases aren't resolved until the SELECT phase, which actually happens after GROUP BY. So you'll want to group by the unaliased expression:

GROUP BY E.FirstName + ' ' + E.LastName

Next, since you're grouping, you will want to aggregate the values

SUM(P.UnitPrice * P.UnitsInStock) as [Total Price]

However, it's unlikely this is what you want since those are coming from the Products table. What you likely want is the sum of UnitPrice * Quantity from the Order Details table

SUM(OD.UnitPrice * OD.Quantity)

Finally, the HAVING clause is also a place where you would put aggregates. Also, to compare a NULL value you cannot use =, you must use IS. If you only want the unshipped orders, remove the HAVING clause and put this in your WHERE clause

WHERE 
 E.EmployeeID = O.EmployeeID
 and O.OrderID = OD.OrderID
 and OD.ProductID = P.ProductID
 and O.ShippedDate IS NULL
Sign up to request clarification or add additional context in comments.

Comments

2

Regarding your question about grouping by aliased columns, see this question.

Regarding your question about the query you're trying to write, you've got two closely related errors that I see. First, when you group by the employee's name, that means you want exactly one record per distinct name. This means that you can't use fields like p.UnitPrice and p.UnitsInStock in your SELECT list, because there is no guarantee that there will be exactly one value of those fields per employee. SQL Server will report this issue with an error like the following.

Msg 8120, Level 16, State 1, Line 4
Column 'p.UnitPrice' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

When you want to select data that is not in your GROUP BY clause, you need to use an aggregate function, i.e. a function that transforms the collection of values that apply to a single record into a single value. In this case, you should look into the SUM function.

The second problem is that you're using HAVING to do something that ought to be done by your WHERE clause. The difference between the two is that the conditions in your WHERE clause are applied to individual records to determine whether or not they'll be included in the result set, before any grouping is done, whereas HAVING conditions are applied to groups as a whole, and will typically use aggregate functions. So for instance, if you wanted to limit your result set to employees whose total order value is above a certain threshold, HAVING would be appropriate. But if you just try to check a single value of ShippedDate in the HAVING clause, you'll get an error like this:

Msg 8121, Level 16, State 1, Line 7
Column 'ShippedDate' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.

Use the WHERE clause instead.

Comments

0

A GROUP BY is processed BEFORE expressions in the select list. Just include E.FirstName and E.LastName in your GROUP BY as these are the base columns that make up your alias.

Comments

0

You need to group by the same expression that you used for your Full Name.

Also, you need to change your IS NULL Check as you cannot do a equality check on null.

SELECT 
 E.FirstName + ' ' + E.LastName  as [Full Name],
 P.UnitPrice * P.UnitsInStock as [Total Price]
FROM Employees E join  Orders O on  E.EmployeeID = O.EmployeeID
join [Order Details] OD on O.OrderID = OD.OrderID
join Products P on OD.ProductID = P.ProductID 
where o.ShippedDate IS NULL 
GROUP BY 
  E.FirstName + ' ' + E.LastName

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.