我有一个查询需要根据多个字段选择一个计算值,但前提是计算结果与现有字段不同。所以假设它看起来像这样:
SELECT ProductID
, PastProfits
, ((UnitPrice - UnitCost) * UnitsSold) AS CurrentProfits
FROM product
WHERE UnitsSold > 10
HAVING CurrentProfits <> PastProfits;
现在,问题是我的结果集中实际上不需要 PastProfits
。但是,如果我将 PastProfits
留在 SELECT
之外,我将无法在 HAVING
子句中访问它。我可以想到几种解决方法:
如上所示,在
SELECT
中包含PastProfits
,并比较HAVING
子句中的字段。 (或者我可以将整个事情放在子查询中,在外部查询中使用WHERE
子句,但这样做可能没有意义。)添加
GROUP BY ProductID, PastProfits
,以便该字段在HAVING
子句中可见。使用用户定义的变量将计算结果存储在
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/