在 'WHERE' 子句 SQL 服务器中使用别名列

Using Alias column in 'WHERE' clause SQL Server

您好,我正在尝试编写 SQL 语句,但在我的 WHERE 子句中使用 'ordercost' 列时遇到问题。

结果集应产生 11 行,日期介于 'Jan 1 1992' 和 'Mar 30 1992' 之间,并且成本也超过 1,500 美元。使用下面的代码,我收到关于 'column not valid' 的错误。

我怀疑我可能需要使用子查询或者可能会偏离方向,但是在搜索了最后 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

我怀疑 SQL 服务器在 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。

在 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

我无法测试这个,因为我没有你的 table 但它解析正常。这个想法是使用 CROSS APPLY 作为表达式计算器。然后你可以在你想要的地方使用你的别名。

在这种情况下,我可能会使用@andrews 解决方案。但是,SELECT 子句中的别名只能在 ORDER BY 子句中引用。如果您确实希望 OrderCost 成为 reference-able 列,您可以使用外部应用来派生它。当你有复杂的计算时,这会很方便,最终可能需要在以后对它们进行额外的计算。这样可以避免您每次都必须重新键入该公式。

编辑:抱歉 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

您可以使用 CTE(通用 Table 表达式)以便在 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