在 WHERE 子句中使用 AS 字段

Posted

技术标签:

【中文标题】在 WHERE 子句中使用 AS 字段【英文标题】:using AS field in WHERE clause 【发布时间】:2018-05-31 02:09:43 【问题描述】:

在下面的例子中:

SELECT op.product_id, op.name, IF(op.sku <> '', op.sku, op.model) AS op_sku,
SUM(op.quantity) AS quantity
FROM order_product op GROUP BY op_sku ORDER BY op_sku ASC LIMIT 0,50

如何在 WHERE 子句中使用op_sku?我是否需要添加另一个选择才能获得所需的值?

编辑原始查询:

SELECT op.product_id, 
       op.name, 
       IF(op.sku <> '', op.sku, op.model) AS model, 
       SUM(op.quantity)                   AS quantity,
       op.sku
FROM   `oc_product` p 
       RIGHT JOIN `oc_order_product` op 
               ON ( p.product_id = op.product_id ) 
       LEFT JOIN `oc_order` o 
              ON ( op.order_id = o.order_id ) 
WHERE  o.order_status_id IN( 17 ) 
GROUP  BY op.sku 
ORDER  BY op.sku ASC 
LIMIT  0, 50 

【问题讨论】:

你想做什么?该查询没有意义,因为您在 select 中有“裸”列。 尝试获取所有带有 sku 的订单产品,如果 sku 不存在则使用模型。实际查询更复杂。 原始查询是否也运行 @TimBiegeleisen 对不起,我的错误,那是我打算做的,而不是实际的查询。已编辑 您通过op.sku 进行聚合,但是您希望mysql 使用您选择中其他列的哪些 值?你看到我的问题了吗?聚合时,您将获取给定 op.sku 值的记录组。 【参考方案1】:

您不能在同一查询的WHERE 子句中使用在SELECT 子句中定义的别名,因为在评估WHERE 子句时它还不可用。一种选择是重复 IF 表达式:

SELECT
    op.product_id,
    op.name,
    IF(op.sku <> '', op.sku, op.model) AS op_sku,
    SUM(op.quantity) AS quantity
FROM order_product op
WHERE IF(op.sku <> '', op.sku, op.model) = <some_value>
GROUP BY op_sku
ORDER BY op_sku
LIMIT 0,50

处理此问题的另一个通用选项是仅包装当前查询,然后从中进行选择。在这种情况下,别名将可用:

SELECT *
FROM
(
    SELECT
        op.product_id,
        op.name,
        IF(op.sku <> '', op.sku, op.model) AS op_sku,
        SUM(op.quantity) AS quantity
    FROM order_product op
    GROUP BY op_sku
) t
WHERE t.op_sku = <some_value>
ORDER BY op_sku
LIMIT 0, 50

作为其他人的一般评论,如果您在按op_sku 分组时选择非聚合列,则您的查询可能会出现问题。理想情况下,其他列应在功能上依赖于op_sku ,它们应包装在聚合函数中。但是,尽管基础查询存在相同的问题,但我给出的一般性答案应该同样有效。

【讨论】:

我想补充一点,公共表表达式将出现在 MySQL 的下一个版本中,这将创建更多选项来处理这个问题。 @BrianDewhirst 是的,而且我还听说将提供一些基本的分析功能。我希望我不必编辑我所有的 MySQL 答案。 答案是对的,但只是第一句话。提供的解决方案不起作用,在这种情况下显然没有任何作用。 @yoda 您的原始查询有问题,因为您在使用GROUP BY 时选择了非聚合列。你真的应该发布实际的查询,我们可以从那里获取它。此答案中给出的两个选项和下面 M Khalid 的建议都将解决您描述的问题。【参考方案2】:

您不能在 where 子句中使用自定义别名,但可以通过 having 子句访问这些​​别名

SELECT op.product_id, op.name, IF(op.sku <> '', op.sku, op.model) AS op_sku,
SUM(op.quantity) AS quantity
FROM order_product op
GROUP BY op_sku 
HAVING op_sku  = @somevalue
ORDER BY op_sku ASC 
LIMIT 0,50

您的查询无效,在 5.7 等较新版本中,它会通过您的错误,因为选择列表中的 product_id 和 name 无效,要么将它们添加到 group by 中,要么对它们应用一些聚合函数以获取它们的值

【讨论】:

以上是关于在 WHERE 子句中使用 AS 字段的主要内容,如果未能解决你的问题,请参考以下文章

查询五子句

如何在 WHERE 子句中使用混合文本和日期字段?

如何在同一字段中使用两个值的 where 子句?

select查询语句

如何在 MySQL 的 WHERE 子句中使用计算字段?

日期字段上的左连接 + Where 子句