如何在SQL语句的WHERE子句中实现别名

时间:2016-04-25 21:48:03

标签: sql sql-server where alias northwind

我现在正在学习SQL,我想要提取某些数据。但是,GROUP BY语句中未识别别名。

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

我知道较新的{​​{1}}(我会改变这些习惯)。此外,实践问题是:

  

对于每位员工,显示尚未发货的所有订单的总价格。

我们正在讨论 Northwind Microsoft数据库。表设计是:

enter image description here

即使别名可行..查询本身也没有解决问题。

4 个答案:

答案 0 :(得分:3)

别名在查询的GROUP BY中不起作用,因为在SELECT阶段之前不会解析别名,而SELECT阶段实际上发生在GROUP BY之后。因此,您需要按未分析的表达式进行分组:

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

接下来,由于您正在进行分组,因此您需要聚合值

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

然而,这不太可能是你想要的,因为它们来自Products表。您可能需要的是订单明细表中UnitPrice * Quantity的总和

SUM(OD.UnitPrice * OD.Quantity)

最后,HAVING子句也是放置聚合的地方。另外,要比较一个不能使用=的NULL值,必须使用IS。如果您只需要未发货的订单,请删除HAVING子句并将其放在WHERE子句中

WHERE 
 E.EmployeeID = O.EmployeeID
 and O.OrderID = OD.OrderID
 and OD.ProductID = P.ProductID
 and O.ShippedDate IS NULL

答案 1 :(得分:2)

关于按别名列分组的问题,请参阅this question

关于您尝试撰写的查询的问题,我发现了两个密切相关的错误。首先,当您按员工的姓名分组时,这意味着您只需要每个不同名称一个记录。这意味着您无法在p.UnitPrice列表中使用p.UnitsInStockSELECT等字段,因为无法保证每位员工只有一个字段值。 SQL Server将报告此问题,并显示如下错误。

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.

如果要在GROUP BY子句中选择的数据,则需要使用聚合函数,即转换适用于单个值的值集合的函数记录成单个值。在这种情况下,您应该查看SUM函数。

第二个问题是,您正在使用HAVING执行应由WHERE子句执行的操作。两者之间的区别在于,WHERE子句中的条件应用于单个记录,以确定在完成任何分组之前它们是否包含在结果集中,而{{1}条件作为一个整体应用于组,通常使用聚合函数。因此,例如,如果您希望将结果集限制为总订单价值高于特定阈值的员工,HAVING将是合适的。但是,如果您只是尝试检查HAVING子句中ShippedDate的单个值,则会收到如下错误:

HAVING

请改用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. 子句。

答案 2 :(得分:0)

GROUP BY在选择列表中处理 BEFORE 表达式。只需在E.FirstName中添加E.LastNameGROUP BY,因为这些是构成别名的基本列。

答案 3 :(得分:0)

您需要按照用于全名的表达式进行分组。

此外,您需要更改IS NULL检查,因为您无法对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