您好我正在尝试使用WHERE子句中的'ordercost'列编写SQL语句并遇到问题。
结果集应生成11行,日期介于'1992年1月1日'和'1992年3月30日'之间,费用也超过1,500美元。使用下面的代码我收到有关'列无效'的错误。
我怀疑我可能需要使用子查询,或者可能会离开,但在搜索过去3小时后,我不确定如何完成此操作。
有人对如何格式化有任何建议吗?
select orders.orderid,
products.productname,
customers.CompanyName,
orderdate = CONVERT(char(11), orders.orderdate, 100),
newshippeddate = CONVERT(char(11), orders.shippeddate + 10 , 100),
ordercost = (OrderDetails.Quantity * Products.UnitPrice)
from orders`enter code here`
INNER JOIN orderdetails ON orders.orderid = orderdetails.orderid
INNER JOIN products ON orderdetails.productid = products.productid
INNER JOIN customers ON orders.customerid = customers.customerid
where orders.orderdate BETWEEN 'Jan 1 1992' AND 'Mar 30 1992'
AND ordercost >= 1500.00
答案 0 :(得分:1)
我怀疑SQL Server在ordercost
动态列上抱怨。如果是,那就试试这个:
select
orders.orderid,
products.productname,
customers.CompanyName,
orderdate = CONVERT(char(11), orders.orderdate, 100),
newshippeddate = CONVERT(char(11), orders.shippeddate + 10 , 100),
ordercost = (OrderDetails.Quantity * Products.UnitPrice)
from orders
INNER JOIN orderdetails ON orders.orderid = orderdetails.orderid
INNER JOIN products ON orderdetails.productid = products.productid
INNER JOIN customers ON orders.customerid = customers.customerid
where (orders.orderdate BETWEEN 'Jan 1 1992' AND 'Mar 30 1992')
AND (OrderDetails.Quantity * Products.UnitPrice) >= 1500.0
由于ordercost
不是真正的专栏,我已将其表达式移至WHERE
。但是,这会使WHERE
条件不具有SARGable。
答案 1 :(得分:1)
在ORDER BY CLAUSE之前,您不能使用列别名(ordercost是别名)。
还有另一种方式:
select orders.orderid,
products.productname,
customers.CompanyName,
computed.orderdate,
computed.newshippeddate,
computed.ordercost
from orders`enter code here`
INNER JOIN orderdetails ON orders.orderid = orderdetails.orderid
INNER JOIN products ON orderdetails.productid = products.productid
INNER JOIN customers ON orders.customerid = customers.customerid
CROSS APPLY (
SELECT
orderdate = CONVERT(char(11), orders.orderdate, 100),
newshippeddate = CONVERT(char(11), orders.shippeddate + 10 , 100),
ordercost = (OrderDetails.Quantity * Products.UnitPrice)
) computed
where (computed.orderdate BETWEEN 'Jan 1 1992' AND 'Mar 30 1992') AND computed.ordercost >= 1500.00
我无法测试这个,因为我没有你的桌子,但它解析好了。我们的想法是使用CROSS APPLY作为表达式求值程序。然后,您可以在需要的位置使用别名。
答案 2 :(得分:0)
在这种情况下,我可能会使用@andrews解决方案。但是,SELECT子句中的别名只能在ORDER BY子句中引用。如果您确实希望OrderCost成为可引用的列,则可以使用外部应用来派生它。当您进行复杂的计算时,这可能很方便,最终可能需要对它们进行额外的计算。这可以防止您每次都必须重新键入该公式。
编辑:我道歉user1443098,我和你一样写这篇文章,看起来像。
select orders.orderid,
products.productname,
customers.CompanyName,
orderdate = CONVERT(char(11), orders.orderdate, 100),
newshippeddate = CONVERT(char(11), orders.shippeddate + 10 , 100),
ordercost = derived.ordercost
from orders
INNER JOIN orderdetails ON orders.orderid = orderdetails.orderid
INNER JOIN products ON orderdetails.productid = products.productid
INNER JOIN customers ON orders.customerid = customers.customerid
OUTER APPLY(SELECT ordercost = OrderDetails.Quantity * Products.UnitPrice) derived
WHERE (orders.orderdate BETWEEN 'Jan 1 1992' AND 'Mar 30 1992') AND derived.ordercost >= 1500.00
答案 3 :(得分:0)
您可以使用CTE(公用表表达式)在WHERE子句中使用列别名。它通常是一个非常小的重构,它几乎总是纯粹的语法糖,不会影响性能或计划选择。
例如:
WITH OrderProductCustomers AS (
select orders.orderid,
products.productname,
customers.CompanyName,
CONVERT(char(11), orders.orderdate, 100) AS orderdate,
CONVERT(char(11), orders.shippeddate + 10 , 100) AS newshippeddate,
(OrderDetails.Quantity * Products.UnitPrice) AS ordercost
from orders
INNER JOIN orderdetails ON orders.orderid = orderdetails.orderid
INNER JOIN products ON orderdetails.productid = products.productid
INNER JOIN customers ON orders.customerid = customers.customerid
)
SELECT orderid, productname, CompanyName, orderdate, newshippeddate, ordercost
FROM OrderProductCustomers
WHERE orderdate BETWEEN 'Jan 1 1992' and 'March 30 1992'
AND ordercost >= 1500.00