解决此问题的一种替代方法是使用子查询包装整个查询,
SELECT *,
sumOfCost - sumOfPrice AS sumOfProfit
FROM
(
SELECT Sales.SaleID,
Sales.StaffID,
Sales.CustomerID,
Sales.Timestamp,
Sales.Refunded,
Sales.PaymentType,
Staff.Forename AS staffForename,
Staff.Surname AS staffSurname,
(
SELECT GROUP_CONCAT(Quantity, ' x ', Name)
FROM SaleItems
WHERE SaleItems.SaleID = Sales.SaleID
) AS itemList,
(
SELECT sum(Cost*Quantity)
FROM SaleItems
WHERE SaleItems.SaleID = Sales.SaleID
) AS sumOfCost,
(
SELECT sum(Price*Quantity)
FROM SaleItems
WHERE SaleItems.SaleID = Sales.SaleID
) AS sumOfPrice
FROM Sales
INNER JOIN Staff
ON Sales.StaffID = Staff.StaffID
WHERE Sales.Deleted = '0'
ORDER BY Timestamp DESC
LIMIT 0, 15
) s
顺便说一句,它们被称为ALIAS
。
ALIAS
不能在定义它们的同一级别上用于计算的原因是服务器在子句FROM
之前执行SELECT
子句。ALIAS
are 在子句上,这SELECT
是完整的 SQL 操作顺序:
- FROM 子句
- WHERE 子句
- GROUP BY 子句
- HAVING 子句
- 选择子句
- ORDER BY 子句
为了更好的性能问题,我宁愿使用JOIN
than subqueries
。
更新 1
SELECT Sales.SaleID,
Sales.StaffID,
Sales.CustomerID,
Sales.Timestamp,
Sales.Refunded,
Sales.PaymentType,
Staff.Forename AS staffForename,
Staff.Surname AS staffSurname,
COALESCE(a.itemList, '') itemList,
COALESCE(b.sumOfCost, 0) sumOfCost,
COALESCE(c.sumOfPrice, 0) sumOfPrice,
COALESCE(b.sumOfCost, 0) - COALESCE(c.sumOfPrice, 0) AS sumOfProfit
FROM Sales
INNER JOIN Staff
ON Sales.StaffID = Staff.StaffID
LEFT JOIN
(
SELECT SaleID, GROUP_CONCAT(Quantity, ' x ', Name) itemList
FROM SaleItems
GROUP BY SaleID
) a ON a.SaleID = Sales.SaleID
LEFT JOIN
(
SELECT SaleID, sum(Cost*Quantity) sumOfCost
FROM SaleItems
GROUP BY SaleID
) b ON b.SaleID = Sales.SaleID
LEFT JOIN
(
SELECT SaleID, sum(Price*Quantity) sumOfPrice
FROM SaleItems
GROUP BY SaleID
) c ON c.SaleID = Sales.SaleID
WHERE Sales.Deleted = '0'
ORDER BY Timestamp DESC
LIMIT 0, 15
更新 2
SELECT Sales.SaleID,
Sales.StaffID,
Sales.CustomerID,
Sales.TIMESTAMP,
Sales.Refunded,
Sales.PaymentType,
Staff.Forename AS staffForename,
Staff.Surname AS staffSurname,
COALESCE(a.itemList, '') itemList,
COALESCE(a.sumOfCost, 0) sumOfCost,
COALESCE(a.sumOfPrice, 0) sumOfPrice,
COALESCE(a.sumOfCost, 0) - COALESCE(a.sumOfPrice, 0) AS sumOfProfit
FROM Sales
INNER JOIN Staff
ON Sales.StaffID = Staff.StaffID
LEFT JOIN
(
SELECT SaleID,
GROUP_CONCAT(Quantity, ' x ', Name) itemList,
SUM(Cost*Quantity) sumOfCost,
SUM(Price*Quantity) sumOfPrice
FROM SaleItems
GROUP BY SaleID
) a ON a.SaleID = Sales.SaleID
WHERE Sales.Deleted = '0'
ORDER BY TIMESTAMP DESC
LIMIT 0, 15