具有计算字段和常规字段的 MySQL

标签 mysql having

我有一个查询需要根据多个字段选择一个计算值,但前提是计算结果与现有字段不同。所以假设它看起来像这样:

SELECT ProductID
     , PastProfits
     , ((UnitPrice - UnitCost) * UnitsSold) AS CurrentProfits
  FROM product
 WHERE UnitsSold > 10
HAVING CurrentProfits <> PastProfits;

现在,问题是我的结果集中实际上不需要 PastProfits。但是,如果我将 PastProfits 留在 SELECT 之外,我将无法在 HAVING 子句中访问它。我可以想到几种解决方法:

  1. 如上所示,在 SELECT 中包含 PastProfits,并比较 HAVING 子句中的字段。 (或者我可以将整个事情放在子查询中,在外部查询中使用 WHERE 子句,但这样做可能没有意义。)

  2. 添加 GROUP BY ProductID, PastProfits,以便该字段在 HAVING 子句中可见。

  3. 使用用户定义的变量将计算结果存储在WHERE 子句中。例如:

    SELECT ProductID
         , @profit AS CurrentProfits
      FROM product
     WHERE UnitsSold > 10
       AND (@profit:=((UnitPrice - UnitCost) * UnitsSold)) <> PastProfits;
    

无论如何,我的问题的重点是:这些方法的相对优缺点是什么?他们中的任何一个更“正确”吗?哪一个可能表现最好?我错过了其他一些方法吗?

最佳答案

编写查询的“正确”方法是复制 where 子句中的表达式:

SELECT ProductID, ((UnitPrice - UnitCost) * UnitsSold) as CurrentProfits
FROM product
WHERE UnitsSold > 10 and ((UnitPrice - UnitCost) * UnitsSold) <> PastProfits;

这是标准的 SQL,它不需要使用任何 MySQL 特定的扩展(例如使用 having 而不使用 group by)。如果您不使用 MySQL,我建议:

SELECT ProductId, CurrentProfits
FROM (SELECT ProductID, ((UnitPrice - UnitCost) * UnitsSold) AS CurrentProfits
      FROM product
      WHERE UnitsSold > 10
    ) p
WHERE CurrentProfits <> PastProfits;

唉,在 MySQL 中,这可能会更昂贵,因为子查询是具体化的。

您的三个选择中,(1) 和 (2) 是合理的。

第三个选项对变量的处理进行了假设。一般来说,MySQL 不保证变量处理的顺序,所以我会避免这样做。

关于具有计算字段和常规字段的 MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24643873/

相关文章:

mysql - 如何在MySQL中使用GROUP By和HAVING

mysql - 具有多列连接的 SQL 查询

php - 可视化来自 mySQL 数据库的数据并将其显示在 html 上?

php表单mysql错误到数据库

mysql - 当我在查询中使用 “GROUP_CONCAT” 和 “HAVING” 时如何计算 MySQL 结果?

mysql - 展开 GROUP BY 和 HAVING 结果集

PHP:在单页网站 (index.php) 上进行 url 重写(带有子域),以处理基于 MySQL 数据的所有页面和 URL

php - 登录表单的 INNER JOIN 在 PHP 中似乎不起作用?

mysql - 查找重复的连接值

SQL - HAVING 与 WHERE