我需要创建一个销售&佣金报告
基本上它是这样(请原谅SaleDate表的blatent疯狂,但我正在简化业务逻辑,实际上以这种方式实现它是有意义的)
SELECT agentName,
SUM(sales.Amount) AS Gross,
SUM(sales.Amount * sales.Commission) AS Commission
FROM agent
INNER JOIN sales ON agent.agentId = sales.agentId
WHERE sales.saleId IN (SELECT saleId FROM saleDate WHERE saleDate.myDate BETWEEN @minDate AND @maxDate)
GROUP BY agentName
所以这个查询工作得非常好。当我需要添加第二个日期范围时会出现问题。
IE,他们想要比较2007年销售额和销售额。 2008年并肩销售。
我目前基本上都有相同的查询,但我已经在sales表中添加了别名并添加了另一个
SELECT agentName,
SUM(sales1.Amount) AS Gross1,
SUM(sales1.Amount * sales1.Commission) AS Commission1,
SUM(sales2.Amount) AS Gross2,
SUM(sales2.Amount * sales2.Commission) AS Commission2,
SUM(sales3.Amount) AS Gross3,
SUM(sales3.Amount * sales3.Commission) AS Commission3
FROM agent
INNER JOIN sales1 ON agent.agentId = sales1.agentId
INNER JOIN sales2 ON agent.agentId = sales2.agentId
INNER JOIN sales3 ON agent.agentId = sales3.agentId
WHERE sales1.saleId IN (SELECT saleId FROM saleDate WHERE saleDate.myDate BETWEEN @minDate1 AND @maxDate1) OR
sales2.saleId IN (SELECT saleId FROM saleDate WHERE saleDate.myDate BETWEEN @minDate2 AND @maxDate2) OR
sales3.saleId IN (SELECT saleId FROM saleDate WHERE saleDate.myDate BETWEEN @minDate3 AND @maxDate3)
GROUP BY agentName
然而,这个查询是永远的(在我取消它之前超过20分钟),原始版本花了不到一秒钟,如果我只使用两个组则需要9秒。
关于如何改善这种表现的任何想法?
我愿意更改此查询的设计。
答案 0 :(得分:1)
如果您的第一个查询工作正常,为什么不只是UNION ALL将新日期转入第二个版本?是的,你不会得到一个透视输出,但这很容易用应用层表示代码修复。
另一种选择是使用CASE。
SELECT agentName,
SUM (CASE WHEN saleDate.myDate BETWEEN @minDate1 AND @maxDate1 THEN sales.Amount ELSE 0 END) AS Gross1,
SUM (CASE WHEN saleDate.myDate BETWEEN @minDate1 AND @maxDate1 THEN sales.Commission ELSE 0 END) AS Commission1,
SUM (CASE WHEN saleDate.myDate BETWEEN @minDate2 AND @maxDate2 THEN sales.Amount ELSE 0 END) AS Gross2,
SUM (CASE WHEN saleDate.myDate BETWEEN @minDate2 AND @maxDate2 THEN sales.Commission ELSE 0 END) AS Commission2
FROM agent
INNER JOIN sales ON agent.agentId = sales.agentId
GROUP BY agentName
答案 1 :(得分:1)
我强烈建议将其拆分为3个独立查询,然后通过UNION
合并结果答案 2 :(得分:0)
检查您的SELECT块,它显示为:
SELECT agentName,
SUM(sales1.Amount)AS Gross1,
SUM(sales1.Amount * sales1.Commission)AS Commission1,
SUM(sales2.Amount)AS Gross2,
SUM(sales2.Amount * sales2.Commission)AS Commission2
并且您正在加入SALES3表,其值在SELECT子句中不存在。这会混淆SQL Server。删除Sales3上的INNER JOIN,它在WHERE块中的OR片段,它将起作用。
OR
将这些项添加到SELECT块。
答案 3 :(得分:0)
这只是在没有任何表格信息(大小,架构,索引)的黑暗中拍摄,但尝试在连接运算符下方移动日期过滤器:
SELECT agentName,
SUM(s1.Amount) AS Gross1,
SUM(s1.Amount * s1.Commission) AS Commission1,
SUM(s2.Amount) AS Gross2,
SUM(s2.Amount * s2.Commission) AS Commission2
FROM agent
INNER JOIN (
SELECT sales1.agentID, Commission, Amount
FROM sales1 WHERE saleId IN (
SELECT saleId FROM saleDate
WHERE saleDate.myDate BETWEEN @minDate1 AND @maxDate1)
) s1 ON agent.agentId = s1.agentId
INNER JOIN (
SELECT sales2.agentID, Commission, Amount
FROM sales2 WHERE saleId IN (
SELECT saleId FROM saleDate
WHERE saleDate.myDate BETWEEN @minDate1 AND @maxDate1)
) s2 ON agent.agentId = s2.agentId;
-- INNER JOIN (
-- SELECT sales3.agentID
-- FROM sales3 WHERE saleId IN (
-- SELECT saleId FROM saleDate
-- WHERE saleDate.myDate BETWEEN @minDate1 AND @maxDate1)
-- ) s3 ON agent.agentId = s3.agentId;