我现在正在学习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数据库。表设计是:
即使别名可行..查询本身也没有解决问题。
答案 0 :(得分:3)
别名在查询的GROUP BY中不起作用,因为在SELECT阶段之前不会解析别名,而SELECT阶段实际上发生在GROUP BY之后。因此,您需要按未分析的表达式进行分组:
GROUP BY E.FirstName + ' ' + E.LastName
接下来,由于您正在进行分组,因此您需要聚合值
SUM(P.UnitPrice * P.UnitsInStock) as [Total Price]
然而,这不太可能是你想要的,因为它们来自Products表。您可能需要的是订单明细表 最后,HAVING子句也是放置聚合的地方。另外,要比较一个不能使用=的NULL值,必须使用IS。如果您只需要未发货的订单,请删除HAVING子句并将其放在WHERE子句中SUM(OD.UnitPrice * OD.Quantity)
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.UnitsInStock
和SELECT
等字段,因为无法保证每位员工只有一个字段值。 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.LastName
和GROUP 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