这是我必须优化的代码,我设法只使用索引并为SUBSTRING语句更改LIKE,将其降低到起始成本的一半。我现在的问题是最后一行中的子查询,以及select中的SUM行,我相信我必须通过创建一个新的表或列来摆脱它们,但是无法完成它。
SELECT
C.LastName as Customer , e.LastName as SalesPerson, s.ProductID,
p.Name as ProductName, SUM( s.Quantity ) as quantity,
SUM ( p.Price * s.Quantity ) as amount
FROM dbo.Sales s, dbo.Customers c, dbo.Employees e, dbo.Products p
WHERE
s.CustomerID = c.CustomerID and
s.ProductID = p.ProductID and
s.SalesPersonID = e.EmployeeID and
p.Name like 'Paint%'
GROUP BY C.LastName , e.LastName , s.ProductID, p.Name
HAVING sum ( s.Quantity ) <
(select AVG(s2.Quantity) from dbo.Sales s2 where s2.ProductID=s.ProductID )
欢迎任何帮助,提前谢谢。
答案 0 :(得分:0)
如果使用SQL Server,您可以使用窗口函数简化这一点:
WITH cte AS ( SELECT C.LastName AS Customer
, e.LastName AS SalesPerson
, s.ProductID
, p.Name AS ProductName
, SUM(s.Quantity) AS quantity
, SUM(p.Price * s.Quantity) AS amount
, SUM(SUM(s.Quantity)) OVER (PARTITION BY s.ProductID)*1.0/SUM(COUNT(*)) OVER (PARTITION BY s.ProductID) AS Avg_Qty
FROM dbo.Sales s
JOIN dbo.Customers c ON s.CustomerID = c.CustomerID
JOIN dbo.Employees e ON s.SalesPersonID = e.EmployeeID
JOIN dbo.Products p ON s.ProductID = p.ProductID
WHERE s.Name LIKE 'Paint%'
GROUP BY C.LastName
, e.LastName
, s.ProductID
, p.Name
)
SELECT *
FROM cte
WHERE quantity < Avg_Qty
添加Name_Category
字段或类似字段以避免使用LIKE
会有所帮助。
答案 1 :(得分:0)
目前无法测试,但我认为这应该有效:
SELECT c.LastName as Customer ,
e.LastName as SalesPerson,
s.ProductID,
p.Name as ProductName,
SUM(s.Quantity) as quantity,
SUM(p.Price * s.Quantity) as amount
FROM dbo.Sales s,
JOIN dbo.Customers c
ON c.CustomerID = s.CustomerID
JOIN dbo.Employees e
ON e.EmployeeID = s.SalesPersonID
JOIN dbo.Products p
ON p.ProductID = s.ProductID
AND p.Name like 'Paint%'
JOIN (SELECT ProductID,
AVG(Quantity) as avg_Quantity
FROM dbo.Sales) s2
ON s2.ProductID = s.ProductID
GROUP BY c.LastName , e.LastName , s.ProductID, p.Name
HAVING sum(s.Quantity) < AVG(s2.avg_Quantity)
答案 2 :(得分:0)
这与您的陈述相同,但速度更快:
SELECT
C.LastName as Customer , e.LastName as SalesPerson, s.ProductID,
p.Name as ProductName, SUM( s.Quantity ) as quantity,
SUM ( p.Price * s.Quantity ) as amount
FROM dbo.Sales s
INNER JOIN dbo.Products p ON s.ProductID = p.ProductID /*AND p.Name like 'Paint%' --optionally place filter here if you like*/
INNER JOIN (SELECT s2.ProductID SalesProductID, AVG(s2.Quantity)AVG_Quantity FROM dbo.Sales s2 GROUP BY s2.ProductID)ProductSales ON ProductSales.SalesProductID = s.ProductID
INNER JOIN dbo.Customers c ON s.CustomerID = c.CustomerID
INNER JOIN dbo.Employees e ON s.SalesPersonID = e.EmployeeID
WHERE p.Name like 'Paint%'
GROUP BY C.LastName , e.LastName , s.ProductID, p.Name