Mysql 在查询中重复使用计算
我想在数据库中创建一个具有少量逻辑的视图。这是为了检查产品的可用性。我创建了一个简化的模式 但是,我需要在多个列中重复使用一个值。以下是我想做的:Mysql 在查询中重复使用计算,mysql,sql,Mysql,Sql,我想在数据库中创建一个具有少量逻辑的视图。这是为了检查产品的可用性。我创建了一个简化的模式 但是,我需要在多个列中重复使用一个值。以下是我想做的: SELECT product.id AS id, SUM(IFNULL(purchase_product.amount,0)) AS amountSold, IFNULL(product.amountAvailable-amountSold,~0) AS amountAvailable, amountAvailable
SELECT
product.id AS id,
SUM(IFNULL(purchase_product.amount,0)) AS amountSold,
IFNULL(product.amountAvailable-amountSold,~0) AS amountAvailable,
amountAvailable>0 AS isAvailable,
FROM product
LEFT JOIN purchase_product ON purchase_product.product_id = product.id
LEFT JOIN purchase ON purchase.id = purchase_product.purchase_id AND purchase.completed = TRUE
GROUP BY product.id
但这失败了,因为我不能重复使用“amountsell”和“amountAvailable”。这使我可以选择重复计算或使用子查询(/加入SELECT/使用更多视图)
这是我能想到的最合理的折衷办法有更优雅的解决方案吗?您可以在具有联接的子查询中执行此操作:
select product.id, s.amountsold,
IFNULL(product.amountAvailable-s.amountSold,~0) AS amountAvailable,
product.amountAvailable>0 AS isAvailable
-- although you probably mean
-- IFNULL(product.amountAvailable-s.amountSold,~0) > 0 as isAvailable
from product join
(SELECT product.id AS id,
SUM(IFNULL(purchase_product.amount,0)) AS amountSold,
IFNULL(product.amountAvailable-amountSold,~0) AS amountAvailable,
amountAvailable>0 AS isAvailable
FROM product LEFT JOIN
purchase_product
ON purchase_product.product_id = product.id LEFT JOIN
purchase
ON purchase.id = purchase_product.purchase_id AND
purchase.completed = TRUE
GROUP BY product.id
) t
on product.id = t.id
在其他数据库中,可以使用windows函数执行类似操作。但是,mysql不支持它们
此外,我认为您希望在减去已售出的金额后可以使用isAvailable,因此我在中添加了它作为建议。我非常喜欢您当前的解决方案,我认为它没有任何实际问题,但我认为这可能稍微简单一些:
SELECT Product.ID,
COALESCE(AmountSold, 0) AS AmountSold,
GREATEST(COALESCE(AmountAvailable, ~0) - COALESCE(AmountSold, 0), 0) AS AmountAvailable,
COALESCE(AmountAvailable, ~0) - COALESCE(AmountSold, 0) > 0 AS IsAvailable
FROM Product
LEFT JOIN
( SELECT Product_ID, SUM(Amount) AS AmountSold
FROM Purchase_Product
INNER JOIN Purchase
ON Purchase.ID = Purchase_ID
WHERE Completed = 1
GROUP BY Product_ID
) sold
ON Sold.Product_ID = Product.ID;
唯一真正的变化是,我在子查询中删除了对product的引用,以减少表扫描的数量,并且稍微改变了计算的逻辑
最后,我在其中添加了grest
,只是为了说明可能存在的任何数据完整性问题,这样您就永远不会有负面产品可用
您可以做进一步的子查询来增加查询的可读性,但这几乎肯定不会提高性能
显示稍微改进的执行计划